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 componentexport 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 againexport { 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); ...