我正在构建一个组件,用于呈现按周分组的 Redux 存储中的数据。由于星期仅与此组件相关,因此我将其值存储为本地状态,如下所示:
constructor(props) {
super(props);
this.state = {
page: 0,
week: this.getWeekNumber(new Date())[1],
year: this.getWeekNumber(new Date())[0]
};
}
这通常是我在组件中所做的事情,并且这种方法从未遇到过任何问题。我有三个按钮,可以根据周重新呈现数据:
...
render() {
...
<Button onClick={() => this.handleRenderWeek("previous")}>
Previous Week
</Button>
<Button onClick={() => this.handleRenderWeek("current")}>
Current Week
</Button>
<Button onClick={() => this.handleRenderWeek("next")}>Next Week</Button>
...
处理渲染的辅助函数定义如下:
handleRenderWeek = action => {
const { week, year, page } = this.state;
switch (action) {
case "previous":
this.setState({
page: 0,
week: week - 1,
year
});
break;
case "current":
this.setState({
page: 0,
week: this.getWeekNumber(new Date())[1],
year: this.getWeekNumber(new Date())[0]
});
break;
case "next":
this.setState(prevState => ({ week: prevState.week + 1 }));
break;
default:
this.setState({
page: 0,
week: this.getWeekNumber(new Date())[1],
year: this.getWeekNumber(new Date())[0]
});
break;
}
this.props.fetchCalendarsAndBookings(week, year, page);
};
问题是,当我单击下周
按钮时,周
状态保持不变。仅当我第二次单击时它才会增加。当我第三次、第四次等等时,它继续正确地递增。
当我点击当前周
和上周
按钮时,按照上述操作,我遇到了完全相同的事情:首先单击状态保持不变(因此发送具有先前状态的 API 调用),然后它开始在第二次点击之后开始工作。
经过一番研究,我发现 setState()
是异步调用的,因此我将上面的代码替换为让 setState()
引用其之前的状态,如下所示:
this.setState((prevState, props) => {
return {
week: prevState.week + 1
};
});
但是这并没有解决问题,我仍然遇到同样的问题。我做错了什么?
最佳答案
经过几个小时的调查,我设法找到了问题的根本原因。显然,发生的情况是 setState()
更新 week
状态较晚。该 API 正在使用旧版本的状态进行调用。
为了解决这个问题,我使用了async/await
:
- 首先更新状态并
等待
- 然后调用 API 获取结果。
代码现在看起来像这样:
handleRenderWeek = async action => {
switch (action) {
case "previous":
await this.decrementWeek();
break;
case "current":
await this.resetWeek();
break;
case "next":
await this.incrementWeek();
break;
default:
await this.resetWeek();
break;
}
console.log("Updated State: ", this.state.week);
await this.props.fetchCalendarsAndBookings(
this.state.week,
this.state.year,
this.state.page
);
};
这里的主要教训有两个:
setState()
是一个异步函数。大宇。- 将
setState()
与 redux thunk 和其他复杂的异步函数混合时,始终使用then()
将它们相应地链接起来,甚至更简单,使用async/await
语法。
关于javascript - React 中的 setState() 未更新 onClick 状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50049690/