【发布时间】:2019-05-24 15:59:36
【问题描述】:
我有以下state:
const[images,setImages] = useState([
{src: 'stringSRC1', selected: false},
{src: 'stringSRC2', selected: false},
{src: 'stringSRC3', selected: false}
]);
我正在使用以下代码更新它(切换选定状态):
function handleImageClick(index) {
props.setImages((prevState)=>{
const aux = Array.from(prevState);
aux[index].selected = !aux[index].selected;
return aux;
});
}
它按预期工作。但我想到了一件事。
当我从 prevState 复制数组时,我正在创建一个新数组,但对象(存储为引用)将保持不变。我已经测试过,它们确实如此像这样复制数组时不会改变。
问题
这是一种不好的做法吗?我是否应该费心深度复制数组,例如创建一个新数组并创建全新的对象?还是这样就好了?
【问题讨论】:
-
仅供参考,answer you've currently accepted 不正确,详细信息in the documentation。
-
@T.J.Crowder 嘿 T.J,感谢您的评论。为什么不正确?看看我使用来自
immer的produce制作的this example。不可变更新会更改数组引用和已修改的每个项目,但不会更改更新未触及的项目的引用。produce不是经常用于执行不可变的 React 状态更新吗?我不会说数组的内容无关紧要,但我想你不必深度克隆它。你同意吗? -
The documentation 很清楚不能直接修改状态项。如果你这样做,它们可能不会重新渲染,包括(但不限于,我不认为)组件在其 props 不变的情况下避免重新渲染的情况(通过
React.memo、PureComponent或 @ 987654336@). -
我没有使用 immer,但从文档和快速检查来看,
produce似乎为您创建了新对象,因此您并没有违反那里的规则。 (如果我将prevState[1]保存到本地,然后在调用produce之后将它与nextState[1]进行比较,这是一个不同的对象——这是文档所说的你需要的,所以一切都很好。) -
React 团队正在为基于函数的 react 编写文档,其中有一个部分简要介绍了相同的问题。 beta.reactjs.org/learn/….
标签: javascript reactjs react-hooks