Состояние массива не обновляется в ComponentDidMount - PullRequest
1 голос
/ 02 мая 2020

У меня странная ситуация, когда у меня есть массив в виде состояния: this.state = { ActivityItem: []}, и я помещаю в него значения из библиотеки, которая вызывает API, например:

   getDataFromKit(dateFrom) {


                Kit.getSamples(stepCountSample, (err, results) => { //api call
                if (err) {
                    return;
                }
                const newData = results.map(item => { return { ...item, name: 'itemAmount' } });
                this.setState({ d: [...this.state.ActivityItem, ...newData] })

            })

Затем я вызываю этот метод из ComponentDidMount () для загружаемого массива

  componentDidMount() {
     this.getDataFromHealthKit(ONEDAYINTERVAL);
    console.log("values are", this.state.ActivityItem)
}

Теперь самая странная часть: каким-то образом массив пуст в ComponentDidMount, но когда я отображаю элементы массива в ответ на функцию render (), он отображает все значения, которые были добавлены правильно. Как это возможно и как я могу это исправить?

Ответы [ 3 ]

0 голосов
/ 02 мая 2020

Обновления состояния имеют асин c характер. Если вы хотите напечатать состояние вскоре после установки своего состояния в компоненте класса, передайте функцию второму аргументу setState.

Как это

componentDidMount() {
  this.getDataFromHealthKit(ONEDAYINTERVAL);
  // remove console.log   
}
...


getDataFromKit(dateFrom) {
    ...
   this.setState({ ActivityItem: [...this.state.ActivityItem, ...newData] }), () => {
    console.log("values are", this.state.ActivityItem) //<---- 
   }
})
 ...
}
0 голосов
/ 02 мая 2020

используйте prevstate при обновлении значения состояния. React setState является асинхронным обновлением и выполняет пакетное обновление. Использование prevState гарантирует, что значение состояния обновляется перед вычислением нового значения состояния.

getDataFromKit(dateFrom) {
    let stepCountSample = {
      startDate: dateFrom.toISOString(),
      type: "Type1"
    };

    Kit.getSamples(stepCountSample, (err, results) => {
      //api call
      if (err) {
        return;
      }
      const newData = results.map(item => {
        return { ...item, name: "itemAmount" };
      });
      this.setState(prevState => {
        ActivityItem: [...prevState.ActivityItem, ...newData];
      });
    });
  }

ДОКУМЕНТАЦИЯ поможет понять концепцию

Также console.log будет напрямую не давать обновленное состояние, так как обновления состояния пакетируются. Вы можете использовать метод обратного вызова для функции setState. Обратный вызов будет выполняться только после успешного обновления значения состояния

0 голосов
/ 02 мая 2020

setState является асинхронным по своей природе. Следовательно, регистрация состояния сразу после установки может привести к такому поведению, но при правильной настройке будет отображаться необходимый контент, который происходит в вашем случае. Также componentDidMount вызывается только один раз в начале, поэтому вы можете проверить журналы в методе componentDidUpdate.

...