我正在构建一个反应应用程序,在按下下一个和后退按钮时呈现不同的组件。我面临的问题是这两个按钮都对前面的按钮按下了反应。就像第一次按下,然后什么都不会发生。如果那时我按回然后它响应按下一个按钮。
class Card extends Component {
constructor()
{
super();
this.state = {
button:"",
i:0
}
}
onClick = (event)=>{
this.setState({button: event.target.id})
if(this.state.button==="1")
{
this.setState({ i: this.state.i + 1 });
}
else if(this.state.button==="2")
{
this.setState({ i: this.state.i - 1 });
}
console.log(this.state.i)
}
render() {
return(
<div className="App">
<div >
<NavBar onButtonClick={this.onClick}/>
<CardList i={this.state.i} />
</div>
</div>
);
}
}
export default Card;
this.setState
需要一点时间来更新整个状态,所以你不能可靠地执行this.setState({button: event.target.id})
然后立即检查this.state.button
- 这可能是状态还没有完成设置。
相反,我建议根据event.target.id
设置条件,如下所示:
if (event.target.id === "1") {
this.setState({ i: this.state.i + 1 });
} else if (event.target.id === "2") {
this.setState({ i: this.state.i - 1 });
}
我会等到你的render
方法的顶部到console.log
你的状态进行调试,因为它将在那时完成更新。
有关如何正确使用setState
的更多信息,您可以看到这个article,尤其是标题为“状态更新可能异步”的部分。
React中的setState
是由React批处理的,基本上它意味着,如果你一个接一个地进行3个状态调用,它们都是顺序调用的。
我建议您阅读official docs了解更多详情。
现在,关于您的问题:您正在根据该状态中的“之前的值”设置状态:
this.setState({ i: this.state.i - 1 });
由于批量模式,这将导致“意外”行为,因为this.state.i
在实际调用时可能会发生变化。
以下是React docs建议做的事情:
setState()并不总是立即更新组件。它可以批量推迟更新或推迟更新。这使得在调用setState()之后立即读取this.state是一个潜在的陷阱。相反,使用componentDidUpdate或setState回调(setState(更新程序,回调))
setState
方法有第二个签名,它接受带签名的函数:(state, props) => stateChange
,其中props
是可选的,如果你不想使用它,则不需要传递它。
你似乎要做的常见错误是在调用this.state
后阅读this.setState
,这是行不通的。
下面的代码并不完美,但希望显示,您需要纠正的内容。
onClick = (event)=>{
var buttonId = event.target.id;
if(buttonId==="1")
{
this.setState((state) => {
return { i: state.i + 1, button: 1 }
});
}
else if(buttonId==="2")
{
this.setState((state) => {
return { i: state.i - 1, button: 2 }
});
}
}
补充阅读:如果您仍然需要了解如何在setState中使用函数,我可以推荐这篇文章:https://medium.freecodecamp.org/functional-setstate-is-the-future-of-react-374f30401b6b