是否有理由在 React 中保持状态完全不可变?

Is there a reason to keep state completely immutable in React?

以状态为例:

const [state, setState] = useState({ x: 1, nested: { y: 2, z: 3 } });

增加 y 值的处理程序的不可变版本如下:

function incrementY() {
    setState((state) => {
      return { ...state, nested: { ...state.nested, y: state.nested.y + 1 } };
    });
}

下一个版本会创建一个新的状态对象,但会改变嵌套对象:

function incrementY() {
    setState((state) => {
      state.nested.y += 1;
      return { ...state };
    });
}

两个版本都会导致组件的重新渲染。现在,让我们假设这个组件呈现一个子组件:

return (
    <div onClick={() => incrementY()}>
      <Child nested={state.nested} />
    </div>
);

如果我理解正确,父组件的重新渲染总是会导致子组件的重新渲染(即使对嵌套对象的引用保持不变)。

我知道不可变状态在需要保留状态历史时很有用(例如,对于 CTRL + Z 功能)。但是有没有我遗漏的特定于 React 的原因?

If I understand correctly, a re-render of the parent component will always lead to a re-render of the child component

默认情况下是,但是子组件可以使用 React.memo(或 class 组件的其他技术)在其 props 没有改变的情况下跳过渲染。如果您改变嵌套对象,然后将该对象传递给子对象,它在子对象看来就像什么都没有改变一样。

所以如果你想能够可靠地使用 React 的工具来跳过渲染,那么你必须让你的状态在所有级别都是不可变的。