React 中奇怪的解构行为
Weird destructuring behavior in React
我有一个深度嵌套的 JSON 对象作为最初使用 useState 挂钩创建的状态 -
const [template, setTemplate] = useState([
{
statement: 'this is top level statement',
nestingLevel: 0,
children: [
{
nestingLevel: 1,
statement:
'this is a statement with such a template',
children: [
{
statement: 'first chart',
nestingLevel: 2,
},
{ statement: 'second chart',
nestingLevel: 2,
},
],
},
],
},
{
statement:
'this is second statement for section with such a metric {{}}',
nestingLevel: 0,
},
]);
我有一个带有 onChange 处理程序的输入元素。
如您所见,每当输入文本发生变化时,我都会根据路径更新一些相关的键值对。我通过使用 lodash 库的 get 和 set 函数来做到这一点。
const handleDataChange = (e, path) => {
console.log('handling the data');
// copy the template
let templateCopy = template;
// create the new object with updated information
const tempObj = _.set(
templateCopy,
`${path}['statement']`,
e.target.value,
);
setTemplate([...tempObj]);
};
问题出在 handleDataChange 函数中。当我执行 setTemplate(tempObj)
时,状态不会更新。但是,当我执行 setTemplate([...tempObj])
(这基本上会产生相同的结果)时,后面的解决方案将按预期工作。
我想知道为什么会这样。是不是因为 lodash 始终将结果作为对象提供,并且解构和重新打包使它再次成为数组,因此它按预期工作?
仅当您改变嵌套 属性 时,对象引用保持不变,并且 React 会进行浅层比较以检测变化,它不会对变化做出反应。
您可以 deepClone
对象,然后像使用 set
一样改变它,然后更新状态。
我有一个深度嵌套的 JSON 对象作为最初使用 useState 挂钩创建的状态 -
const [template, setTemplate] = useState([
{
statement: 'this is top level statement',
nestingLevel: 0,
children: [
{
nestingLevel: 1,
statement:
'this is a statement with such a template',
children: [
{
statement: 'first chart',
nestingLevel: 2,
},
{ statement: 'second chart',
nestingLevel: 2,
},
],
},
],
},
{
statement:
'this is second statement for section with such a metric {{}}',
nestingLevel: 0,
},
]);
我有一个带有 onChange 处理程序的输入元素。
如您所见,每当输入文本发生变化时,我都会根据路径更新一些相关的键值对。我通过使用 lodash 库的 get 和 set 函数来做到这一点。
const handleDataChange = (e, path) => {
console.log('handling the data');
// copy the template
let templateCopy = template;
// create the new object with updated information
const tempObj = _.set(
templateCopy,
`${path}['statement']`,
e.target.value,
);
setTemplate([...tempObj]);
};
问题出在 handleDataChange 函数中。当我执行 setTemplate(tempObj)
时,状态不会更新。但是,当我执行 setTemplate([...tempObj])
(这基本上会产生相同的结果)时,后面的解决方案将按预期工作。
我想知道为什么会这样。是不是因为 lodash 始终将结果作为对象提供,并且解构和重新打包使它再次成为数组,因此它按预期工作?
仅当您改变嵌套 属性 时,对象引用保持不变,并且 React 会进行浅层比较以检测变化,它不会对变化做出反应。
您可以 deepClone
对象,然后像使用 set
一样改变它,然后更新状态。