reactjs - React useState 改变了我不变的初始状态
问题描述
我的selectItem
事件改变了initialState
我故意实现的,以保持不变。
Panel.js
import React, { useState } from "react";
import "./Panel.css";
import Item from "./Item";
const initialState = [
{ text: 1, isSelected: false },
{ text: 2, isSelected: false },
{ text: 3, isSelected: false },
{ text: 4, isSelected: false },
{ text: 5, isSelected: false }
];
export default function Panel() {
const [items, setItems] = useState(initialState);
const selectItem = k => {
console.log(k);
const updatedItems = [...initialState];
updatedItems.find(item => item.text === k).isSelected = true;
setItems(updatedItems);
};
return (
<div className="Panel">
{items.map(item => (
<Item
key={item.text}
text={item.text}
isSelected={item.isSelected}
clicked={selectItem}
/>
))}
</div>
);
}
项目.js
import React from "react";
import "./Item.css";
export default function Item({ text, isSelected, clicked }) {
return (
<div className="Item" onClick={() => clicked(text)}>
{isSelected ? <div style={{ backgroundColor: "red" }}>{text}</div> : text}
</div>
);
}
解决方案
这样看,你的数组是一个对象数组,每个索引(item)都是对某个特定对象的引用。
基本上,当您创建updatedItems
数组时,您会将其所有引用分散到一个新的“引用对象的数组”中。因此,从技术上讲,您使用的是完全相同的对象。一旦你选择了一个并改变它,你就改变了同时引用initialState
和items
引用的对象。
您正在做的是数组的浅层克隆(副本)。
如果您想进行深度克隆,一个简单的方法是:JSON.parse(JSON.stringify(initialState))
.
您还可以使用 lodash/cloneDeep https://lodash.com/docs/4.17.15#cloneDeep等实用程序
但请记住,深度克隆也可能非常昂贵,而且并不总是理想的结果。
推荐阅读
- jquery - 动态添加的复选框未触发 onCheck 或 onUncheck 事件
- r - 如何使用 R 上传/下载 Googledrive 包?
- vba - 使用 VBA 在 MS Access 查询文本数据类型字段中按金额过滤
- laravel - 删除链接而不是按钮 laravel
- java - Spring 循环依赖,即使使用通过 setter 注入
- graphql - GraphQL 数据存储在哪里?
- python - 为什么链接列表上的索引匹配失败?
- ios - 如何将对象传递给应该快速确认两个协议的函数?
- c# - 添加 NuGet 包后 Clickonce 部署大小膨胀
- url - Google News XML API:使用国家/语言参数