【问题标题】:How to use variable within component inside function in react-native?如何在 react-native 的函数内部组件中使用变量?
【发布时间】:2020-08-17 18:25:40
【问题描述】:

我正在从实时数据库 (firebase) 中检索一些数据,但是,当我尝试在数据库引用调用之外检查“级别”的值时,我得到一个未定义的值,尽管它在引用中工作。

有没有办法允许访问 react-native 组件中的变量 'levels'?

我在网上看到了一些使用 this.setState 来实现此目的的示例,但似乎没有任何方法可以在函数中执行此操作。

function LevelsScreen() {
    const reference = database()
    .ref()
    .once('value')
    .then(snapshot => {
      //get Levels from db
      let levels = [];
      snapshot.forEach((child) => {
          levels.push(child.key);
      })
      console.log(levels);
  
  });
    return (
      <SafeAreaView style={styles.categories}>
        {/* Horizontal Scrollbox for Main Categories */}
        <ScrollView horizontal={true} style={styles.scrollView}>
          <View>

            {/* This function should call LevelCard to return the components with the proper titles*/}
            {levels.map(element => {
                return (<LevelCard
                level={element}/>)
                })
            }

          </View>
        </ScrollView>
      </SafeAreaView>
    );
}

【问题讨论】:

    标签: android reactjs function react-native mobile


    【解决方案1】:
    1. 您应该使用 state 让 react 知道要渲染什么。
    2. 从数据库中获取数据时,我们会更新状态。
    3. 更新状态会触发 React 中的重新渲染,这表示 React 在屏幕上渲染新内容。
    4. 然后,您可以向用户展示您的新状态。
    function LevelsScreen() {
      // use state so that the react can know when the update the screen.
      const [levels, setLevels] = React.useState(null);
    
      // upon the component mount, we call the database.
      React.useEffect(() => {
        database()
          .ref()
          .once("value")
          .then((snapshot) => {
            //get Levels from db
            const levels = snapshot.map((child) => child.key);
            // update the state so react knows to re-render the component
            setLevels(levels);
          });
      }, []);
    
      return (
        <SafeAreaView style={styles.categories}>
          {/* Horizontal Scrollbox for Main Categories */}
          {levels ? (
            <ScrollView horizontal={true} style={styles.scrollView}>
              <View>
                {/* This function should call LevelCard to return the components with the proper titles*/}
                {levels.map((element) => {
                  return <LevelCard level={element} />;
                })}
              </View>
            </ScrollView>
          ) : (
            {/* show spinner when the levels is not got from the server */}
            <ActivityIndicator />
          )}
        </SafeAreaView>
      );
    }
    
    

    【讨论】:

      【解决方案2】:

      我认为如果你可以使用 Promises 会更好。

      function LevelsFunction() {
          return Promise(resolve=> {
          database()
          .ref()
          .once('value')
          .then(snapshot => {
          const levels = [];
          snapshot.forEach((child) => {
            levels.push(child.key);
          })
          console.log(levels);
          resolve(levels)
      });
      

      现在可以使用 async/await 或 then 从您想要的任何地方访问 LevelsFunction。

      例如:

      componentDidMount(){
          const levels = LevelsFunction().then(res => res);
          console.log(levels);
      }
      

      async componentDidMount(){
          const levels = await LevelsFunction();
          console.log(levels);
      }
      

      我强烈建议您不要在类渲染函数中使用它。

      【讨论】:

        猜你喜欢
        • 2021-08-15
        • 1970-01-01
        • 2016-09-28
        • 2018-12-24
        • 2021-11-13
        • 2021-11-20
        • 2019-03-12
        • 2019-11-19
        • 1970-01-01
        相关资源
        最近更新 更多