我有一个奇怪的情况,我有一个数组作为一个状态。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()函数的返回中显示Array的元素时,它显示了所有被正确添加的值。这怎么可能,我怎么才能解决这个问题?
setState本质上是异步的。因此,在设置后立即记录状态可能会产生这种行为,但如果设置正确,它将显示所需的内容,这就是你的情况。另外,componentDidMount在一开始只被调用一次,所以你可以在componentDidUpdate方法中检查日志。
状态更新是async性质的。如果你想在类组件中设置好状态后很快就打印状态,那么就在ComponentDidUpdate方法的第二个参数中传递一个函数。setState
.
像这样
componentDidMount() {
this.getDataFromHealthKit(ONEDAYINTERVAL);
// remove console.log
}
...
getDataFromKit(dateFrom) {
...
this.setState({ ActivityItem: [...this.state.ActivityItem, ...newData] }), () => {
console.log("values are", this.state.ActivityItem) //<----
}
})
...
}
使用 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函数。只有在成功更新状态值后,回调才会运行。