javascript - 使用 State Hook 正确设置状态

标签 javascript reactjs

我目前正在学习 React 并试图了解如何在函数组件中正确更新状态。

我从 React 文档中的“状态和生命周期”部分了解到,如果它使用以前的状态,则应该更新状态,如下所示:

// Correct
this.setState((state, props) => ({
  counter: state.counter + 1
}));

而不是

// Wrong
this.setState({
  counter: this.state.counter + 1,
});

由于 this.props 和 this.state 可能会异步更新,因此您不应依赖它们的值来计算下一个状态。 ( Reference )

现在我想通过使用 State Hook useState 的函数组件来实现相同的目的。 作为示例,如何更新功能组件中的状态 React docs有以下代码片段:

<button onClick={() => setCount(count + 1)}>
  Click me
</button>

这相当于类组件中的以下代码:

<button onClick={() => this.setState({ count: this.state.count + 1 })}>
  Click me
</button>

但这不是“错误”的解决方案吗,因为它直接依赖于国家?

最佳答案

But isn't this the "wrong" solution because it relies directly on the state?

setState 将新状态合并到旧状态中。并以“零碎”的方式进行,例如新状态可以包含旧状态数据的一小部分。因此,在 setState 主体中保留旧状态并使用
this.setState(oldState => ({ ...oldState, someProp: true }) )
“显式”更好,因为它表明您对 setState 无论如何都会执行的操作不抱任何幻想:即使您没有这样做,也会进行合并。

useState 用新状态替换旧状态,因此访问 oldState 的需求不那么迫切。虽然我不介意。

对于异步更新setStateuseState都可以批量更新。尽管 useState 在处理待处理的 Promise 时不会进行批处理,这与示例中的 count + 1 等现成可用值相反。

回到setState,还有一个原因可以解释为什么setState(oldState => ({...}) 的风格更好。记住,setState 无论如何都会进行合并。如果使用 setState(newValue) 风格,则与批处理相结合,可能会导致 React 执行以下代码:
Object.assign(oldState, newValue1, newValue2, newValue3)
其中值 newValueX 是批量更新。 Object.assign 确保“最后更新获胜”。如果一系列 newValueX 表示连续尝试递增同一计数器,那么它可能无法按预期工作。因此 setState 的其他风格更好。使用 useState 和批处理,这种危险似乎仍然存在。

关于javascript - 使用 State Hook 正确设置状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58025996/

相关文章:

javascript - 如何使用 React Native Video 显示外部字幕?

javascript - 如何从对象列表中获取唯一值?

javascript - 使用react-konva在Canvas上制作GIF动画

javascript - 如何使用 Jest 和新的 React lazy 16.6 API 测试快照

javascript - Flexbox 在 anchor 内生长

asp.net - umbraco tiny MCE 3 Internet Explorer 插入链接错误

javascript - 启动 Tracker 的自动运行功能需要什么?

reactjs - React Router 和 Express 冲突

javascript - String.format 不是函数

javascript - 在 jQuery 中,如何在每个循环中动态删除数组元素?