如果将状态值分配给另一个变量然后更改状态,React 不会触发重新渲染
React does not trigger rerender if you assign state value to another variable and then change the state
由于我缺乏知识和经验,我偶然发现了一个奇怪的行为。
我有一个在另一个内部调用的组件,看起来像这样:
<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);
};
有人可以解释为什么会这样吗?
发生这种情况是因为 const updatedRoles=roles
在内存中为完全相同的对象创建了另一个名称,因此您对 updatedRoles
所做的一切都会反映在 roles
中,换句话说,您改变了状态. roles.slice()
另一方面创建一个新的独立对象。当你将这个新对象传递给 setState
时,React 可以看到差异并触发重新渲染,但是当你只是通过另一个名称将它传递给 roles
时,React 认为不需要做任何事情,因为 updatedRoles
和 roles
是一回事。
在您的第一个示例中,您使用相同的数组实例来更新状态。
React 只检查浅层相等性。它不是迭代项目。
.slice()
创建一个新数组。
如果您的状态是数组,请始终创建一个新数组。
Slice 创建原始数组的浅表副本,这意味着它 returns 是与 roles
本身不同的对象,即使其内容可能相同。
当您执行 setRoles(roles)
时,您实际上是在内存中发送完全相同的对象,并且当 React 在决定是否重新渲染之前比较 props 时,它没有检测到任何差异。但是,当您执行 setRoles(roles.slice())
时,您在内存中传递了一个不同的变量,因此 React 认为 props 发生了变化并重新渲染。
由于我缺乏知识和经验,我偶然发现了一个奇怪的行为。 我有一个在另一个内部调用的组件,看起来像这样:
<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);
};
有人可以解释为什么会这样吗?
发生这种情况是因为 const updatedRoles=roles
在内存中为完全相同的对象创建了另一个名称,因此您对 updatedRoles
所做的一切都会反映在 roles
中,换句话说,您改变了状态. roles.slice()
另一方面创建一个新的独立对象。当你将这个新对象传递给 setState
时,React 可以看到差异并触发重新渲染,但是当你只是通过另一个名称将它传递给 roles
时,React 认为不需要做任何事情,因为 updatedRoles
和 roles
是一回事。
在您的第一个示例中,您使用相同的数组实例来更新状态。
React 只检查浅层相等性。它不是迭代项目。
.slice()
创建一个新数组。
如果您的状态是数组,请始终创建一个新数组。
Slice 创建原始数组的浅表副本,这意味着它 returns 是与 roles
本身不同的对象,即使其内容可能相同。
当您执行 setRoles(roles)
时,您实际上是在内存中发送完全相同的对象,并且当 React 在决定是否重新渲染之前比较 props 时,它没有检测到任何差异。但是,当您执行 setRoles(roles.slice())
时,您在内存中传递了一个不同的变量,因此 React 认为 props 发生了变化并重新渲染。