简体   繁体   中英

How do I call a component in another file? React Native

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM