就像@MichaelRovinsky 说的:
给每个组件一个唯一的标识符。删除组件时,
通过 id 找到它并从数组中删除。不要使用索引,因为它是
不持久
因此,您需要使用唯一标识符。
为此,您可以使用react-uuid。
首先,我将您的步骤重新定义为:
export class Step {
Id;
Type;
Value;
}
所以,你的默认数据应该是这样的:
const defaultSteps = [
{ Type: ALPHA, Id: uuid(), Value: 0 },
{ Type: ALPHA, Id: uuid(), Value: 0 },
{ Type: ALPHA, Id: uuid(), Value: 0 }
];
我还将Alpha 组件的index 属性更改为id。
在您的 renderSteps 函数中:
case ALPHA:
return (
<Alpha
id={step.Id}
onChange={onValueChange}
onDelete={index > 0 ? () => onDelete(step) : null}
key={step.Id}
/>
);
看,现在id 属性和key 是相同且唯一的。
onValueChange事件:
const onValueChange = (id, newValue) => {
let currentSteps = [...steps];
const step = currentSteps.filter((f) => f.Id === id)[0];
step.Value = newValue;
setSteps(currentSteps);
setValues(currentSteps.map((m) => m.Value));
};
因此,在不跟踪索引的情况下设置值变得更加简单。
onDelete事件:
const onDelete = (step) => {
let currentSteps = [...steps];
const index = currentSteps.indexOf(step);
currentSteps.splice(index, 1);
setSteps(currentSteps);
setValues(currentSteps.map((m) => m.Value));
};
由于您所有需要的属性现在都在单个对象中,因此处理steps 和values 状态要容易得多。
工作演示CodeSandbox。