I am new to React Native and I am confused about how to call a specific component function ('runDemo' in SQLData.js) in another file in order to get the data that I will then push into another component file to display. I am trying to keep my code as clean and understandable as possible so I am trying to split codes into separate files without cluttering.
The flow of my code is: Apps.js gets data from SQLData.js and sends it as a prop to FlatList.js which will then render it.
The results of my files below is throwing an "Invariant Violation. Tried to get frame for index out of range index NaN"
These are the 3 files below:
Apps.js - main file
import React from 'react';
import CustomList from './components/FlatList';
import SQLData from './components/SQLData';
export default function App() {
return(
//Not too sure if this is the correct way!
var database = <SQLData />
<CustomList data={database}/>
);
};
FlatList.js - Used to return the Flatlist with data
import React, {useState} from 'react';
...
import ListItem from './ListItem';
/**
* Handles the FlatList structure.
*/
export default function CustomList(props) {
//Sets up Getter , Setter , Initial Data
const [data, setData] = useState(props.data);
...
//This is UI that will be returned
return(
//div block
<View style = {styles.contentContainer}>
<FlatList
ListHeaderComponent = {header}
//Sets the data for FlatList
data = {data}
keyExtractor = { (item) => (item.id).toString()}
//Takes each item from the database and separates them into separate div and applies style to each one
ItemSeparatorComponent = { () => <View style={styles.itemSeparator}></View>}
contentContainerStyle={ {borderBottomColor:'grey', borderBottomWidth: 1} }
//Gets item and index pair and creates a ListItem with those as props
renderItem = { ({item, index}) => <ListItem item={item} index={index}/>}
/>
</View>
);
};
SQLData.js - Used to read Data from local db file
import React, { useState } from 'react';
import SQLite from 'react-native-sqlite-storage';
...
export default function importData(props) {
const [helperArray, setArray] = useState([]);
/** 1. First function to be called **/
function runDemo() {
loadAndQueryDB();
}
/** 2. Called when runDemo is called **/
/* assigns variable 'db' to opened Database */
/* Calls queryPeople(db) */
function loadAndQueryDB() {
db = SQLite.openDatabase({name : "users.db"}, openCB, errorCB);
queryPeople(db);
}
/** 3. Called when loadAndQueryDB is called **/
/* Get the DB and applies a SQL call that if successful will call queryPeopleSuccess*/
function queryPeople(db) {
...
}
/** 4. [SUCCESS] Called when queryPeople SQL execution is successful **/
/* results - a ResultSet object */
function queryPeopleSuccess(tx, results) {
var len = results.rows.length;
let localArray = [];
//Go through each item in dataset
for (let i = 0; i < len; i++) {
let row = results.rows.item(i);
localArray.push(row);
}
setArray(localArray);
}
return ({helperArray});
};
UPDATE: FIXED
Apps.js
import React from 'react';
import CustomList from './components/FlatList';
import { Utils } from './helpers/Index.js';
/**
* App.js calls CustomList
*/
//This uses functional instead of class component
export default function App() {
const data = Utils.runDemo();
return(
<CustomList data={data}/>
);
};
NEW FOLDER CALLED 'helpers' containing Index.js and SQLData.js
Index.js
import * as Utils from './SQLData.js';
// Export again
export {
Utils,
};
SQLData.js
import React from 'react';
import SQLite from 'react-native-sqlite-storage';
let db;
function runDemo() {
return loadAndQueryDB();
}
function loadAndQueryDB() {
db = SQLite.openDatabase({ name: "users.db" }, openCB, errorCB);
return queryPeople(db);
}
function queryPeople(db) {
const data = db.transaction((tx) => {
tx.executeSql('SELECT * FROM users', [], queryPeopleSuccess,
errorCB);
});
return data;
}
function queryPeopleSuccess(tx, results) {
...
return localArray;
}
export {
runDemo,
};
In my Components Folder "./components/ FlatList.js
export default function CustomList(props) {
const [data, setData] = useState(props.data);
...
Seems like your SQLData is just a helper function and not a React component, I am not sure why are u using state inside since you can return the result directly return localArray;
Now, if we remove the being a component thing, you can use it just like another function after importing it
import SQLData from './components/SQLData';
<CustomList data={SQLData.runDemo()}/>
UPDATE
Since your function is inside another function you have 2 options, make it accessible outside by returning it
function importData() {
function runDemo() {
console.log("hi");
}
return {
runDemo: runDemo
};
}
import SQLData from './components/SQLData';
const data = SQLData();
<CustomList data={data.runDemo()}/>
or remove the parent function so all the functions are independent, this way the original answer would work
import SQLData from './components/SQLData';
<CustomList data={SQLData.runDemo()}/>
You don't pass like this
var database = <SQLData />
<CustomList data={database}/>
You have to simply pass like this
<CustomList data={SQLData}/>
Because of the SQLData will return some value.
you can use useContext because data is exchanged
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.