setState после загрузки массива из firebase - PullRequest
0 голосов
/ 30 марта 2020

Я видел подобные вопросы в Интернете, но ни одно из их решений не помогло мне.

Я создаю приложение в React Native, которое загружает информацию из firebase, а затем отображает ее. Я хочу загрузить объекты из firebase, поместить их в массив, а затем установить состояние, чтобы класс повторно отображал и отображал его после загрузки.

Информация загружается нормально, но я не могу найти способ вызвать setState после загрузки массива. Я попробовал обещания и попытался использовать другую функцию в качестве обратного вызова, но у меня пока ничего не получалось. Он всегда выполняет setState до загрузки массива. Я не знаю, будет ли использование setTimeout каким-то образом хорошим решением.

Вот часть кода (я хочу обновить jArray в this.state, а затем заново отрендерить страницу) :

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 голосов
/ 03 апреля 2020

Итак, в конце концов я нашел решение своей проблемы: { ссылка }

Мой код выглядит так:

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))
        }
      })
  });
}

Это своего рода хитрый со словами «это» и «это», но теперь все работает нормально.

0 голосов
/ 30 марта 2020

Может быть, вы можете сделать что-то вроде этого:

  // 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...
    }
  };
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...