如果您将状态值分配给另一个变量然后更改状态,React 不会触发重新渲染
Posted
技术标签:
【中文标题】如果您将状态值分配给另一个变量然后更改状态,React 不会触发重新渲染【英文标题】:React does not trigger rerender if you assign state value to another variable and then change the state 【发布时间】:2021-05-27 18:12:38 【问题描述】:由于缺乏知识和经验,我偶然发现了一种奇怪的行为。 我在另一个内部调用了一个组件,如下所示:
<CustomSelectionButtons
values=roleTypes
label="Roles:"
onSelect=setUserRoles
selected=roles
/>
roles 是一个状态变量,通过 onSelect 方法 (setUserRoles) 设置。 这里是:
const setUserRoles = (button: AccountsAndRolesUnion) =>
const updatedRoles: AccountsAndRolesUnion[] = roles; //this is the state variable.
/* doing something with the local **updatedRoles** array */
setRoles(updatedRoles);
;
如果我使用这样的代码,组件不会在 setRoles 钩子调用后重新渲染。 但是,如果我用 roles.slice() 分配局部变量,一切都会按预期工作,组件会重新呈现。 所以,这行得通:
const setUserRoles = (button: AccountsAndRolesUnion) =>
const updatedRoles: AccountsAndRolesUnion[] = roles.slice(); //slicing the state variable.
/* doing something with the local **updatedRoles** array */
setRoles(updatedRoles);
;
谁能解释为什么会这样?
【问题讨论】:
【参考方案1】:Slice 创建原始数组的浅表副本,这意味着它返回的对象与roles
本身不同,即使其内容可能相同。
当你做setRoles(roles)
时,你实际上是在内存中发送完全相同的对象,当 React 在决定是否重新渲染之前比较 props 时,它没有检测到任何差异。但是,当您执行 setRoles(roles.slice())
时,您在内存中传递了一个不同的变量,因此 React 认为 props 和重新渲染发生了变化。
【讨论】:
【参考方案2】:在您的第一个示例中,您使用相同的数组实例来更新状态。
React 只检查浅层相等。它不是迭代项目。
.slice()
创建一个新数组。
如果您的状态是数组,请始终创建一个新数组。
【讨论】:
【参考方案3】:发生这种情况是因为const updatedRoles=roles
为内存中完全相同的对象创建了另一个名称,因此您对updatedRoles
所做的一切都会反映在roles
中,换句话说,您会改变状态。另一方面,roles.slice()
创建一个新的独立对象。当你将这个新对象传递给 setState
时,React 可以看到差异并触发重新渲染,但是当你只是将它传递给 roles
时,React 不需要做任何事情,因为 updatedRoles
和 @ 987654328@是同一个东西。
【讨论】:
以上是关于如果您将状态值分配给另一个变量然后更改状态,React 不会触发重新渲染的主要内容,如果未能解决你的问题,请参考以下文章
为什么将一个对象的值分配给另一个对象的值,然后重新分配原始对象会更改两个对象?