创建新的状态数组与在使用状态钩子中改变以前的状态



阅读有关useState钩子的问题 我在想setState.我总是故意使用带有回调选项的setState来访问以前的状态,并将所有元素放在数组中。

因此,我为功能组件中的表示做了一个简单的示例:

const [elems, setElems] = useState([]);
const addElemsMutate = (count) => {
const newArray = [...elems];
for (let i = 0; i < count; i++) {
newArray.push(i);
}
setElems(newArray);
};
const addElemsUsePreviousState = (count) => {
for (let i = 0; i < count; i++) {
setElems(previousElems => [...previousElems, i]);
}
}
return <>
<button onClick={() => addElemsMutate(10)}>addElemsMutate</button>
<button onClick={() => addElemsUsePreviousState(10)}>addElemsUsePreviousState</button>
{elems.map((e, index) => <span key={index}>{e}</span>)}
</>

问题

我知道setState异步的,排队更改并且不应像文档所述直接更改。

结果窗体这两个操作在 UI 上看起来相同。所以我的问题是关于我在addElemsMutate函数中有什么:

  1. 这被认为是一种不好的做法吗?
  2. 如果我仍然使用该选项(如果有的话(,缺点是什么?

谢谢!

这里发生了很多可能不是故意的:

  • 正如评论中提到的,addElemsMutate()实际上并没有改变状态。
  • addElemsUsePreviousState()count状态更改排队,而不是由addElemsMutate()调度的单个更改。

您可以将useState()的回调形式与useCallback()结合使用,作为小型性能优化。

const addElemsCallback = useCallback(count => {
setElems(elems => {
const newElems = [...elems];
for (let i = 0; i < count; i++) {
newElems.push(i);
}
return newElems;
});
}, [setElems]);

由于setElems永远不会改变,addElemsCallback也不会改变,这是你唯一需要作为依赖项传递的东西。

React 更改状态的最佳实践是将当前状态复制到新变量中,在那里进行更改,然后更改状态(就像您在示例中所做的那样(。

这是因为,当您直接更改状态时,而不是深度复制以前的状态,您会遇到引用问题,这可能会留下一些难以找到的错误。

相关内容

  • 没有找到相关文章

最新更新