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.
根据我的实验,如果您有一个对象作为反应状态 (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.