我的组件在不应该的时候改变了它的道具
My component is mutating its props when it shouldn't be
我有一个组件,它从父级的 prop 中获取一个数组,然后将其设置为一个状态。然后我修改这个数组,目的是将 prop 的修改版本发送回父级。
我很困惑,因为当我在应用程序中修改状态时,我在控制台注销了 prop 对象,尽管从未被函数触及,但它正在同时被修改。
这是代码的简化版本:
import React, { useEffect, useState } from 'react';
const ExampleComponent = ({ propObj }) => {
const [stateArr, setStateArr] = useState([{}]);
useEffect(() => {
setStateArr(propObj.arr);
}, [propObj]);
const handleStateArrChange = (e) => {
const updatedStateArr = [...stateArr];
updatedStateArr[e.target.dataset.index].keyValue = parseInt(e.target.value);
setStateArr(updatedStateArr);
}
console.log(stateArr, propObj.arr);
return (
<ul>
{stateArr.map((stateArrItem, index) => {
return (
<li key={`${stateArrItem._id}~${index}`}>
<label htmlFor={`${stateArrItem.name}~name`}>{stateArrItem.name}</label>
<input
name={`${stateArrItem.name}~name`}
id={`${stateArrItem._id}~input`}
type="number"
value={stateArrItem.keyValue}
data-index={index}
onChange={handleStateArrChange} />
</li>
)
})}
</ul>
);
};
export default ExampleComponent;
据我了解,propObj
不应根据此代码进行更改。但不知何故,它反映了组件的 stateArr
更新。感觉自己疯了。
propObj
|stateArr
in state 已正确更新并且 returns 新数组引用,但您忽略了复制正在更新的元素。 updatedStateArr[e.target.dataset.index].keyValue = parseInt(e.target.value);
是状态突变。请记住,每个元素也是对原始元素的引用。
使用功能状态更新并将当前状态映射到下一个状态。当索引匹配时,也将元素复制到新对象中并更新所需的属性。
const handleStateArrChange = (e) => {
const { dataset: { index }, value } = e.target;
setStateArr(stateArr => stateArr.map((el, i) => index === i ? {
...el,
keyValue: value,
} : el));
}
我有一个组件,它从父级的 prop 中获取一个数组,然后将其设置为一个状态。然后我修改这个数组,目的是将 prop 的修改版本发送回父级。
我很困惑,因为当我在应用程序中修改状态时,我在控制台注销了 prop 对象,尽管从未被函数触及,但它正在同时被修改。
这是代码的简化版本:
import React, { useEffect, useState } from 'react';
const ExampleComponent = ({ propObj }) => {
const [stateArr, setStateArr] = useState([{}]);
useEffect(() => {
setStateArr(propObj.arr);
}, [propObj]);
const handleStateArrChange = (e) => {
const updatedStateArr = [...stateArr];
updatedStateArr[e.target.dataset.index].keyValue = parseInt(e.target.value);
setStateArr(updatedStateArr);
}
console.log(stateArr, propObj.arr);
return (
<ul>
{stateArr.map((stateArrItem, index) => {
return (
<li key={`${stateArrItem._id}~${index}`}>
<label htmlFor={`${stateArrItem.name}~name`}>{stateArrItem.name}</label>
<input
name={`${stateArrItem.name}~name`}
id={`${stateArrItem._id}~input`}
type="number"
value={stateArrItem.keyValue}
data-index={index}
onChange={handleStateArrChange} />
</li>
)
})}
</ul>
);
};
export default ExampleComponent;
据我了解,propObj
不应根据此代码进行更改。但不知何故,它反映了组件的 stateArr
更新。感觉自己疯了。
propObj
|stateArr
in state 已正确更新并且 returns 新数组引用,但您忽略了复制正在更新的元素。 updatedStateArr[e.target.dataset.index].keyValue = parseInt(e.target.value);
是状态突变。请记住,每个元素也是对原始元素的引用。
使用功能状态更新并将当前状态映射到下一个状态。当索引匹配时,也将元素复制到新对象中并更新所需的属性。
const handleStateArrChange = (e) => {
const { dataset: { index }, value } = e.target;
setStateArr(stateArr => stateArr.map((el, i) => index === i ? {
...el,
keyValue: value,
} : el));
}