感觉有点笨,我用 React 已经 2 年了,一直认为你必须使用 setState
使用对象的新副本以避免改变状态。然而,这个例子改变了状态并使用了 setState
使用相同的对象引用没有任何问题。
为什么这行得通?
Working Code Pen
const { useState } = React;
const Counter = () => {
const [countObject, setCountObject] = useState({count: 0});
const onClick = () => {
countObject.count = countObject.count + 1;
setCountObject(countObject); // mutated object, same reference
}
return (
<div>
<p>You clicked {countObject.count} times</p>
<button onClick={onClick}>
Click me
</button>
</div>
)
}
ReactDOM.render(<Counter />, document.getElementById('app'))
最佳答案
您的 codepen 使用的是 React 16.7 的 alpha 版本。 Hooks 是在 16.8 中发布的,所以要可靠地使用 hooks,你应该使用 16.8 或更高版本(在 React 的非 alpha 版本中):
您可以通过单击 JavaScript Pane 上代码笔中的齿轮图标来更新上述两个链接的版本号。
请注意,以下代码段使用 16.7.0-alpha.2 并遇到您遇到的相同问题:
const { useState } = React;
const Counter = () => {
const [countObject, setCountObject] = useState({count: 0});
const onClick = () => {
countObject.count = countObject.count + 1;
setCountObject(countObject);
}
return (
<div>
<p>You clicked {countObject.count} times</p>
<button onClick={onClick}>
Click me
</button>
</div>
)
}
ReactDOM.render(<Counter />, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.7.0-alpha.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.7.0-alpha.2/umd/react-dom.production.min.js"></script>
<div id="app"></div>
但是,将您的版本更改为 16.8 或更高版本可以解决此问题(在撰写本文时,我们已更新至 v17.0.2):
const { useState } = React;
const Counter = () => {
const [countObject, setCountObject] = useState({count: 0});
const onClick = () => {
countObject.count = countObject.count + 1;
setCountObject(countObject);
}
return (
<div>
<p>You clicked {countObject.count} times</p>
<button onClick={onClick}>
Click me
</button>
</div>
)
}
ReactDOM.render(<Counter />, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>
<div id="app"></div>
关于javascript - React 函数式组件,setState 和不变性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70664935/