如何防止初始状态数组发生变异?
How can I prevent initial state array from being mutated?
在我的容器组件中,我有一个状态,它使用我用作数据的对象进行初始化。
我克隆状态数组以防止初始状态发生变异,但它仍然发生变异,我不想发生这种情况,因为稍后我需要将当前状态与初始状态进行比较。
who 系统保存在 CubeOfTruthSystem 组件中
function CubeOfTruthSystem() {
const [cubeIndex, setCubeIndex] = useState(0);
const [faceIndex, setFaceIndex] = useState(0);
return (
<React.Fragment>
<CubeSelector handleClick={(index) => setCubeIndex(index)} />
<CubeContainer cubeIndex={cubeIndex} faceIndex={faceIndex} />
<FaceSelector handleClick={(index) => setFaceIndex(index)} />
<button id="reset-face" onClick={() => console.log(CubeOfTruth)}>
Reset
</button>
</React.Fragment>
);
}
状态的父组件如下所示:
function CubeContainer({ cubeIndex, faceIndex }) {
const [cube, setCube] = useState(CubeOfTruthData);
const handleCellClick = (id, row) => {
const cubeClone = [...cube];
const item = cubeClone[cubeIndex].faces[faceIndex].data[0].find(
(item) => item.id === id
);
item.state = "active";
cubeClone[cubeIndex].faces[faceIndex].data = activateAdjacentCells(
id,
row,
cubeClone[cubeIndex].faces[faceIndex].data,
item
);
setCube(cubeClone);
};
return (
<div id="cube-container">
{cube[cubeIndex].faces[faceIndex].data.map((row) => {
return row.map((item) => {
return (
<CubeItem item={item} handleClick={handleCellClick} key={item.id} />
);
});
})}
</div>
);
}
这是子组件
function CubeItem({ item, handleClick }) {
const handleBgClass = (cellData) => {
if (cellData.state === "inactive") {
return cellData.bg + "-inactive";
} else if (cellData.state === "semi-active") {
return cellData.bg + "-semi-active";
} else {
return cellData.bg;
}
};
return (
<button
className={`cell-item ${handleBgClass(item)}`}
disabled={item.state === "inactive" ? true : false}
onClick={() => handleClick(item.id, item.row)}
/>
);
}
在 CubeOfTruth 组件中,我试图获取初始状态(即 CubeOfTruth 数组),但在更改状态后,cube、cubeClone 和 CubeOfTruth 都具有相同的值。
如何确保 CubeOfTruth 永远不会发生变异?
您正在尝试克隆立方体数组,但您正在制作它的浅表副本。
如果你想防止嵌套属性的突变,你应该制作一个深拷贝。
替换为:
const cubeClone = [...cube];
有了这个:
const cubeClone = JSON.parse(JSON.stringify(cube));
或者使用像lodash
这样的库
const cubeClone = _.cloneDeep(cube)
在我的容器组件中,我有一个状态,它使用我用作数据的对象进行初始化。
我克隆状态数组以防止初始状态发生变异,但它仍然发生变异,我不想发生这种情况,因为稍后我需要将当前状态与初始状态进行比较。
who 系统保存在 CubeOfTruthSystem 组件中
function CubeOfTruthSystem() {
const [cubeIndex, setCubeIndex] = useState(0);
const [faceIndex, setFaceIndex] = useState(0);
return (
<React.Fragment>
<CubeSelector handleClick={(index) => setCubeIndex(index)} />
<CubeContainer cubeIndex={cubeIndex} faceIndex={faceIndex} />
<FaceSelector handleClick={(index) => setFaceIndex(index)} />
<button id="reset-face" onClick={() => console.log(CubeOfTruth)}>
Reset
</button>
</React.Fragment>
);
}
状态的父组件如下所示:
function CubeContainer({ cubeIndex, faceIndex }) {
const [cube, setCube] = useState(CubeOfTruthData);
const handleCellClick = (id, row) => {
const cubeClone = [...cube];
const item = cubeClone[cubeIndex].faces[faceIndex].data[0].find(
(item) => item.id === id
);
item.state = "active";
cubeClone[cubeIndex].faces[faceIndex].data = activateAdjacentCells(
id,
row,
cubeClone[cubeIndex].faces[faceIndex].data,
item
);
setCube(cubeClone);
};
return (
<div id="cube-container">
{cube[cubeIndex].faces[faceIndex].data.map((row) => {
return row.map((item) => {
return (
<CubeItem item={item} handleClick={handleCellClick} key={item.id} />
);
});
})}
</div>
);
}
这是子组件
function CubeItem({ item, handleClick }) {
const handleBgClass = (cellData) => {
if (cellData.state === "inactive") {
return cellData.bg + "-inactive";
} else if (cellData.state === "semi-active") {
return cellData.bg + "-semi-active";
} else {
return cellData.bg;
}
};
return (
<button
className={`cell-item ${handleBgClass(item)}`}
disabled={item.state === "inactive" ? true : false}
onClick={() => handleClick(item.id, item.row)}
/>
);
}
在 CubeOfTruth 组件中,我试图获取初始状态(即 CubeOfTruth 数组),但在更改状态后,cube、cubeClone 和 CubeOfTruth 都具有相同的值。 如何确保 CubeOfTruth 永远不会发生变异?
您正在尝试克隆立方体数组,但您正在制作它的浅表副本。 如果你想防止嵌套属性的突变,你应该制作一个深拷贝。
替换为:
const cubeClone = [...cube];
有了这个:
const cubeClone = JSON.parse(JSON.stringify(cube));
或者使用像lodash
这样的库const cubeClone = _.cloneDeep(cube)