我是React的新手,有一本书告诉我,使用setState方法作为下面的示例是不正确的:
...
constructor(props) {
super(props);
this.state = {
counter: 0,
hasButtonBeenClicked: false
}
}
render() {
return (
<button onClick={ this.handleClick }>
Click
</button>
)
}
handleClick = () => {
this.setState({ counter: this.state.counter + 1 });
this.setState({ hasButtonBeenClicked: this.state.counter > 0 });
}
...
因为React异步地更改状态数据,并且可以选择将多个更新组合在一起以提高性能。
我明白了,但是由于React异步执行更改。有时,第一个setState方法将在第二个setState方法之前被首先调用的机会和机会,这只是一个概率问题。但是无论我尝试了多少次,总是总是先调用第二个setState方法,为什么?
答案 0 :(得分:3)
尽管它们是异步执行的,但是在同一浏览器和/或同一硬件上进行测试时,您不太可能看到差异。不同的浏览器以稍微不同的方式优化指令集,这是检查性能的最佳选择(这也是为什么尽管商业上Chrome通常“足够好”,但仍建议在所有主流桌面浏览器上进行测试的原因)。
执行此操作的最佳方法(假设您希望它们按特定顺序触发)是按以下方式链接setState
调用:
handleClick = () => {
this.setState({ counter: this.state.counter + 1 }, () => {
this.setState({ hasButtonBeenClicked: this.state.counter > 0 })
});
}
但是无论如何我都会建议采用另一种设计-将hasButtonBeenClicked
逻辑与计数器绑定会带来问题。
答案 1 :(得分:1)
this.state
。使用setState
的回调变体,从那里获取当前状态。这将明确警告您避免出现“状态已更改,但状态尚未更改”的情况。然后2.将这两个更新简单地放入setState
的一次运行中:
this.setState((prevState) => ({
counter: prevState.counter + 1,
hasButtonBeenClicked: prevState.counter + 1 > 0 }));
答案 2 :(得分:0)
如果您要一次更新许多状态,请将它们全部分组在同一setState
中:
代替:
this.setState({foo: "one"}, () => {
this.setState({bar: "two"});
});
只需执行以下操作:
this.setState({
foo: "one",
bar: "two"
});
或者您的情况:
handleClick = () => {
this.setState({
counter: this.state.counter + 1,
hasButtonBeenClicked: this.state.counter > 0
});
}
答案 3 :(得分:0)
是的,React异步更改状态数据以提高性能。 对于您的情况,您应编写如下代码:
handleClick = () => {
const counter = this.state.counter + 1;
this.setState({
counter: counter,
hasButtonBeenClicked: counter > 0
});
}
或者,您可以使用setState的回调参数。