Javascript setState()在单击时处于React not updating状态
我正在构建一个组件,用于呈现按周分组的Redux存储区中的数据。由于周仅与此组件相关,因此我将其值存储为本地状态,如下所示:Javascript setState()在单击时处于React not updating状态,javascript,reactjs,react-redux,Javascript,Reactjs,React Redux,我正在构建一个组件,用于呈现按周分组的Redux存储区中的数据。由于周仅与此组件相关,因此我将其值存储为本地状态,如下所示: constructor(props) { super(props); this.state = { page: 0, week: this.getWeekNumber(new Date())[1], year: this.getWeekNumber(new Date())[0] }; } handl
constructor(props) {
super(props);
this.state = {
page: 0,
week: this.getWeekNumber(new Date())[1],
year: this.getWeekNumber(new Date())[0]
};
}
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);
};
this.setState((prevState, props) => {
return {
week: prevState.week + 1
};
});
这通常是我在我的组件中所做的,并且这种方法从来没有任何问题。我有三个按钮将根据周重新呈现数据:
...
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>
...
问题是,当我单击nextweek
按钮时,week
状态保持不变。它仅在我再次单击时递增。当我第三次、第四次等时,它继续正确地递增
当我点击本周
和前一周
按钮时,我经历了完全相同的事情:首先点击状态保持不变(因此发送一个带有前一状态的API调用),然后在第二次点击之后开始工作
经过一些研究,我发现setState()
是异步调用的,因此我将上面的代码替换为setState()
,参考其以前的状态,如下所示:
constructor(props) {
super(props);
this.state = {
page: 0,
week: this.getWeekNumber(new Date())[1],
year: this.getWeekNumber(new Date())[0]
};
}
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);
};
this.setState((prevState, props) => {
return {
week: prevState.week + 1
};
});
然而,这并没有解决问题,我仍然有同样的问题。我做错了什么?下面代码段中的“下一步”按钮按预期工作。其他按钮由于未定义的过程而失败。我尽可能地把它和你的代码保持在一起。我不认为您的问题包含在您在问题中提供的代码中
类Hello扩展了React.Component{
建造师(道具){
超级(道具);
此.state={
第周:0
};
}
handleRenderWeek(行动){
const{week,year,page}=this.state;
开关(动作){
“以前”一案:
这是我的国家({
页码:0,
周:第1周,
年
});
打破
案例“当前”:
这是我的国家({
页码:0,
周:this.getWeekNumber(新日期())[1],
年份:this.getWeekNumber(新日期())[0]
});
打破
案例“下一个”:
this.setState(prevState=>({week:prevState.week+1}));
打破
违约:
这是我的国家({
页码:0,
周:this.getWeekNumber(新日期())[1],
年份:this.getWeekNumber(新日期())[0]
});
打破
}
}
render(){
返回(
你好{this.props.name},周是{this.state.week}
此.handleRenderWeek(“先前”)}>
前一周
this.handleRenderWeek(“当前”)}>
本周
本.handleRenderWeek(“下一周”)}>下周
);
}
}
ReactDOM.render(
,
document.getElementById('容器')
);代码>
经过数小时的调查,我终于找到了问题的根本原因。显然发生的情况是,setState()
更新周
状态的时间晚了。正在使用旧版本的状态调用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 thunks和其他复杂的异步函数混合使用时,始终使用then()
或更简单的async/await
语法相应地链接它们
我隐约记得这与标记为已处理的单击事件有关,但我不确定。初始状态week
prop是否正确?handleRenderWeek
是在render()
之前还是之后声明的?@IvanBurnaev你是什么意思?@DJ。宣布哪一个地方没有区别