React 的函数式 setState 如何确定哪些字段已更新?

How does React's functional setState determine which fields have been updated?

根据我的实验,如果您有一个对象作为反应状态 (let [state, setState] = useState({})),并且您执行类似

的操作
setState(s => {
    s.a = 42;
    return s;
})

它不会重新渲染依赖于 s.a 的组件。 另一方面,如果你这样做

setState(s => {...s, a: 42});

它将重新渲染所有依赖于 s 的任何字段的组件。 所以在我看来,它实际上只查看返回的闭包对象引用是否与它已经拥有的状态相同,并做出是否重新渲染所有内容或什么都不渲染的二元选择。

对吗?

有没有什么方法可以更新状态,使其只重新渲染依赖于例如s.a?

CONTEXT,如果有帮助的话:我的应用程序需要这个,因为性能变得不切实际。我的应用程序从 API 端点检索 JSON 信息,其中包含一个 'fields' 列表,描述了用户可用于输入数据的输入字段。用户完成后,应用程序会在单个 json 中提交此数据。所以所有的输入组件都是通过一个单一的功能状态来控制的,每个字段都有一个 属性 (有时我需要能够以编程方式更新一些字段)。性能令人望而却步,因为每次用户在其中一个字段中键入一个字符时,所有字段(现在很多)都是 updated/re-rendered。遗憾的是,我无法为每个字段创建新状态,因为事先不知道字段的数量。

作为开始之前的说明,这不行,而且通常不起作用。将所有 React state/props 视为不可变的,否则你会遇到问题。

setState(s => {
    s.a = 42;
    return s;
})

无法选择性地 re-render 您的组件,setState 上的突变不 re-render children 依赖于 s.a 的原因是因为您当你像这样更新时,组件根本不会 re-render 因为 s 的引用没有改变,所以反应看不到有变化。

当 parents re-render 时使 children 而不是 re-render 的唯一方法是使用 React.memo、PureComponent 或 shouldComponentUpdate。这些必须应用于 children 而不是 parent.