从Firebase加载数组后的setState

时间:2020-03-30 10:04:32

标签: javascript reactjs firebase react-native setstate

我在网上看到了类似的问题,但没有一个解决方案对我有用。

我正在React Native中构建一个应用程序,该应用程序从firebase加载信息,然后显示它。我想从firebase加载对象,将它们放入数组中,然后设置状态,以便该类在加载后重新呈现并显示。

信息可以很好地加载,但是在数组加载后我找不到找到setState的方法。我尝试了Promise,并尝试使用另一个函数作为回调,但是对我来说还没有任何作用。它总是在加载数组之前执行setState。我不知道以某种方式使用setTimeout是否会是一个好的解决方案。

这是其中的一些代码(我想在this.state中更新jArray,然后重新渲染页面):

constructor(props){
  super(props);
  this.state = {
    jArray: []
  }
}

componentDidMount(){         
   this.getJ(); 
}

async getJ(){

  let jArray = [];
  let ref = database.ref('users/' + fb.auth().currentUser.uid + '/usersJ');
  let snapshot = await ref.once('value');

  let itemProcessed = 0;
  let hhh = await snapshot.forEach(ch => {
     database.ref('J/' + ch.val()).once('value')
      .then(function(snapshot1){
        jArray.push(snapshot1);
        itemProcessed++;
        console.log(itemProcessed);
        if(snapshot.numChildren()===jArray.length){
          JadArray = jArray
        }
      })
  });

}

谢谢(:

2 个答案:

答案 0 :(得分:0)

也许您可以执行以下操作:

  // don't forget to use an arrow function to bind `this` to the component
  getJ = async () => {
    try {
      const ref = database.ref('users/' + fb.auth().currentUser.uid + '/usersJ');
      const snapshot = await ref.once('value');

      // it might be easier just to start by getting the data into an object you can use like this
      const dataObj = snapshot.val();

      // extract the keys
      const childKeys = Object.keys(dataObj);

      // use the keys to create a function that makes an array of all the promises we want
      const createPromises = () =>
        childKeys.map(childKey => database.ref('J/' + childKey).once('value'));

      // await ALL the promises before moving on
      const jArray = await Promise.all(createPromises());

      // now you can set state
      this.setState({ jArray });

      // remember to catch any errors
    } catch (err) {
      console.warn(err);
      // you might want to do something else to handle this error...
    }
  };
}

答案 1 :(得分:0)

因此,最终我找到了解决问题的方法,其来源为:https://stackoverflow.com/a/47130806/3235603

我的代码如下:

async getJ(){

  let jArray = [];
  let ref = database.ref('users/' + fb.auth().currentUser.uid + '/usersJ');
  let snapshot = await ref.once('value');

  let itemProcessed = 0;
  let that = this;
  let hhh = await snapshot.forEach(ch => {
     database.ref('J/' + ch.val()).once('value')
      .then(function(snapshot1){
        jArray.push(snapshot1);
        itemProcessed++;
        console.log(itemProcessed);
        if(snapshot.numChildren()===jArray.length){
          JadArray = jArray
          that.setState({
            jadArray : jArray,
            dataLoaded : true
          },() => console.log(that.state))
        }
      })
  });
}

使用'this'和'that'有点棘手,但现在一切正常。

相关问题