关于react的状态更新,如果逻辑如下:
modules = modules.map((module) => {
// module为{}对象
if (module.name === "info") {
// ❌ 错误:直接修改原对象
module.isShow = type !== "test";
return module; // 返回的是同一个引用
}
return module;
});上述写法会有问题,正确的写法应该是什么呢?
modules = modules.map((module) => {
if (module.name === "info") {
// ✅ 正确:创建新对象
return { ...module, isShow: type !== "test" };
}
return module;
});| 写法 | 返回结果 | React 是否检测到变化 |
|---|---|---|
{ ...module, isShow: newValue } | 新对象,新引用 | ✅ 是,会重新渲染 |
module.isShow = newValue; return module; | 原对象,相同引用 | ❌ 否,不会重新渲染 |
React 的渲染优化机制(特别是浅比较)选择为什么比较引用而非内容❓❓
1.比较引用是 O(1) 时间复杂度的操作,而深度比较内容可能是 O(n) 甚至更复杂
2. React 遵循 "引用不可变性" 模式,这源于函数式编程思想:
(第一反应是更新时创建新对象,不会造成内存泄漏吗❓)
在使用不可变更新时,我们的操作是用新引用替换旧引用。一旦旧引用被替换,并且没有其他地方持有它,旧的不可变对象就变成了“不可达”的数据,最终会被垃圾回收器安全清理
// 示例:安全的不可变更新
const [state, setState] = useState({ items: [] });
const addItem = (newItem) => {
// 创建全新的对象,赋予新引用
const newState = { items: [...state.items, newItem] };
setState(newState); // 新引用替换旧引用
// 此时,旧的 `state` 对象如果没有其他变量引用它,将在下次GC时被回收
// 旧的 `state.items` 数组同理
};1.状态管理
// 更新对象状态
const [user, setUser] = useState({ name: 'John', age: 25 });
setUser({ ...user, age: 26 }); // ✅ 只更新age,保留其他属性
// 更新数组中的对象
const [todos, setTodos] = useState([{ id: 1, text: 'Learn React', done: false }]);
setTodos(todos.map(todo =>
todo.id === 1 ? { ...todo, done: true } : todo
));2.
