考虑简单的状态钩子:
const [count, setCount] = React.useState(0);
我想增加或减少计数。基本上做钩子文档中显示的相同操作。
但作为旧this.setState
函数的已知事实:
因为 this.props 和 this.state 可能会异步更新,所以你 不应依赖其值来计算下一个状态。
基于旧状态更新状态的正确方法是:
this.setState((state) => ({
counter: state.counter + 1
}));
同样的事情适用于setCount
吗? 或者我可以确定count
始终是最新的?
useState
钩子的工作方式与this.setState
不同。调用 setter(setCount
以下示例中(确实异步工作,但由于在呈现功能组件期间不会更改count
因此评估是确定性的。
以下示例从 React 文档中的 Hooks 一目了然地逐字复制,是 100% 安全的(在未挂载的组件上调用方法时不会有任何错误(,并且将按预期运行:
function Example() {
// Declare a new state variable, which we'll call "count"
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
只有在引用 state 时需要多次调用setCount
,才需要使用将函数传递给setCount
的功能更新。请注意,这并不是因为setState
是异步的,而是因为count
直到下一次渲染才会更新。
例如,这将是一个问题:
<button
onClick={() => {
setCount(count + 1)
setCount(count + 1) // since `count` is not dynamically updated mid-render, this evaluates to the same value as above
}}
/>
在实践中,这种模式相对较少。您不会以这种方式在单个函数中多次调用 setter。相反,如果您将 setter 作为子项的道具传递,并且这些子级引用由 setter 控制的状态,那么您将使用功能更新模式。但是,即使在这种情况下,React 也会使用每个连续值重新渲染组件。
至于担心这是否是一种可靠和/或推荐的方法,React 文档对此事有这样的说法(来源(:
你可能会听到一个建议,即始终编写类似
setCount(c => c + 1)
的代码,如果你设置的状态是从以前的状态计算出来的。它没有害处,但也并不总是必要的。在大多数情况下,这两种方法之间没有区别。React 始终确保对于有意的用户操作,例如点击,
count
状态变量将在下次点击之前更新。这意味着单击处理程序不会在事件处理程序的开头看到"过时"count
。但是,如果在同一事件中执行多个更新,则更新程序可能会有所帮助。如果访问状态变量本身不方便,它们也很有帮助(在优化重新渲染时可能会遇到这种情况(。
如果您更喜欢一致性而不是稍微更冗长的语法,那么如果您设置的状态是从以前的状态计算而来的,则始终编写更新程序是合理的。如果它是根据其他某个状态变量的先前状态计算得出的,则可能需要将它们合并到一个对象中并使用化简器。
我不确定确切的逻辑和count
状态的用例,但一般来说,您需要调用
setCount(count + 1);
或者,使用回调进行功能更新
setCount(prev => prev + 1);
如果您想更新您的状态。但是,请注意,状态的更新可以是异步的,这与类组件的setState()
的工作方式类似。您可以参考 useState 文档以获取更多详细信息。