我目前正在学习React,但我不完全理解为什么这是错误的:
// Correct
this.setState((state, props) => ({
counter: state.counter + props.increment
}));
这是正确的:
setState()
有人可以给我一个真实的例子吗?我可以使用接受功能的“ {{1}}的第二种形式”吗?
这是link
答案 0 :(得分:1)
假设您有一个CheckBoxComponent
,您可以在构造函数中像这样初始化其状态:
this.state = {enabled: true}
您要在用户单击复选框时更新其状态。因此,您可以编写以下点击处理程序:
function toggleCheckbox() {
this.setState({enabled: ???});
}
这种情况就是setState的第二种类型。点击处理程序应写为:
function toggleCheckbox() {
this.setState(prevState => ({enabled: !prevState.enabled}));
}
答案 1 :(得分:0)
由于this.props和this.state可能会异步更新,因此您 不应依赖于它们的值来计算下一个状态。
1)只要您不使用当前状态/属性来计算下一个状态,就可以在大多数情况下使用此摘要。
例如,此代码段仅用于从github提取数据并更新为其状态。我们可以将一个对象放在this.setState()中。
class FetchGithub extends react.Component{
state = {
//...
};
componentDidMount() {
fetch('https://api.github.com/repos/facebook/react/commits')
.then(data => this.setState(data.json()))
.catch(err => this.setState(err));
}
}
2)但是一旦方案要使用当前状态/属性为下一个状态进行计算,则需要放置一个函数来确保我们的当前状态已经更新。
this.setState((state, props) => ({
counter: state.counter + props.increment
}));
[已更新]
因为props是从该组件的父级或redux的reducer传递的参数,这意味着处理需要时间。因此,您还需要确保道具是最新的。
让我们再次看看您的代码示例。应该有2个组成部分:
因此,正确的流程是用户单击+ 1 / -1,AdjustComponent将道具传递到DisplayComponent。然后,DisplayComponent通过其当前状态和AdjustComponent发送的道具来更新其状态。并显示在屏幕上。
但是,如果用户单击-1然后非常非常快地+1,或者用户的计算机突然要承受巨大的负载来影响其浏览器性能,该怎么办?这样,当您使用此代码段时:
this.setState({
counter: state.counter + props.increment
});
尚未从AdjustComponent接收到最新的道具(应为+1),但DisplayComponent已使用旧的props.increment(为-1,导致错误的结果)进行了更新。