前言
React 的核心原则之一是:状态(state)是不可变的(immutable) ,你不能直接修改 useState 返回的状态值。
一、 为什么必须用 slice ?
React状态不可直接修改!slice这里直接调用,会生成新的数组(引用不同),react会检测到状态变化并渲染;但是直接通过数组的索引去修改的话,不会触发react的更新机制;
这里是关于react需要拷贝的内容汇总
https://blog.csdn.net/COCOLI_BK/article/details/159386310
- 一维数组
javascript
import { useState } from 'react';
function Demo() {
const [list, setList] = useState([1,2,3]);
const handleUpdate = () => {
const newList = list.slice(); // 创建浅拷贝(新数组)
newList[0] = 100; // 修改新数组
setList(newList); // 更新状态触发重渲染
};
return (
<div>
<div>{list.join(',')}</div>
<button onClick={handleUpdate}>更新</button>
</div>
);
}
- 多维数组
javascript
// 对象数组
function ObjArrDemo() {
const [users, setUsers] = useState([{id:1, name:'张三'}]);
const handleUpdate = () => {
const newUsers = users.slice();
newUsers[0] = { ...newUsers[0], name:'李四' }; // 内层对象拷贝
setUsers(newUsers);
};
return <button onClick={handleUpdate}>改名字</button>;
}
// 多维数组
function MultiArrDemo() {
const [arr, setArr] = useState([[1,2], [3,4]]);
const handleUpdate = () => {
const newArr = arr.slice();
newArr[0] = [...newArr[0]]; // 内层数组拷贝
newArr[0][1] = 200;
setArr(newArr);
};
return <button onClick={handleUpdate}>改数值</button>;
}
二、slice () 替代方法
javascript
// 1. 扩展运算符
const newls = [...list]
// 2. Array.from
const newList = Array.from(list);
// 3. map(适合修改/过滤)
const newList = list.map(item => item*2)
三、注意事项
- 浅拷贝仅覆盖第一层,多维 / 对象数组需拷贝内层数据;
- 优先用展开运算符
[...arr],语义更清晰; - 仅修改数组时拷贝,避免无意义性能开销。