Reactjs 如何删除通过函数渲染的组件
请参考 我在删除通过函数渲染的组件时遇到问题。由于组件不应以状态存储,因此我将其类型存储在父组件状态的数组中。函数迭代该数组以呈现组件。当我尝试按索引删除特定组件时,React不会更新我要保留的组件中的道具(索引)(即:将索引2处的组件更改为索引1)。相反,它会呈现已经位于该索引处的组件。我的Codesandbox示例演示了这种行为Reactjs 如何删除通过函数渲染的组件,reactjs,Reactjs,请参考 我在删除通过函数渲染的组件时遇到问题。由于组件不应以状态存储,因此我将其类型存储在父组件状态的数组中。函数迭代该数组以呈现组件。当我尝试按索引删除特定组件时,React不会更新我要保留的组件中的道具(索引)(即:将索引2处的组件更改为索引1)。相反,它会呈现已经位于该索引处的组件。我的Codesandbox示例演示了这种行为 如何删除以这种方式呈现的组件(通过使用父级状态填充道具的函数)?有没有其他方法可以渲染这些组件?就像@MichaelRovinsky说的: 为每个组件指定一个唯一标
如何删除以这种方式呈现的组件(通过使用父级状态填充道具的函数)?有没有其他方法可以渲染这些组件?就像@MichaelRovinsky说的:
为每个组件指定一个唯一标识符。删除组件时, 按id查找它并从数组中删除。不要使用索引,因为它是 不持久 因此,您需要使用唯一标识符 为此,您可以使用 首先,我将您的步骤重新定义为:
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 }
];
我还用id
更改了Alpha
组件的index
属性
在renderSteps
函数中:
case ALPHA:
return (
<Alpha
id={step.Id}
onChange={onValueChange}
onDelete={index > 0 ? () => onDelete(step) : null}
key={step.Id}
/>
);
因此,在不跟踪索引的情况下,设置值变得简单得多
onDelete
事件:
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));
};
const onDelete = (step) => {
let currentSteps = [...steps];
const index = currentSteps.indexOf(step);
currentSteps.splice(index, 1);
setSteps(currentSteps);
setValues(currentSteps.map((m) => m.Value));
};
由于所有必需的属性现在都位于单个对象中,因此处理步骤
和值
状态要容易得多
工作演示在。就像@MichaelRovinsky说的:
为每个组件指定一个唯一标识符。删除组件时, 按id查找它并从数组中删除。不要使用索引,因为它是 不持久 因此,您需要使用唯一标识符 为此,您可以使用 首先,我将您的步骤重新定义为:
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 }
];
我还用id
更改了Alpha
组件的index
属性
在renderSteps
函数中:
case ALPHA:
return (
<Alpha
id={step.Id}
onChange={onValueChange}
onDelete={index > 0 ? () => onDelete(step) : null}
key={step.Id}
/>
);
因此,在不跟踪索引的情况下,设置值变得简单得多
onDelete
事件:
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));
};
const onDelete = (step) => {
let currentSteps = [...steps];
const index = currentSteps.indexOf(step);
currentSteps.splice(index, 1);
setSteps(currentSteps);
setValues(currentSteps.map((m) => m.Value));
};
由于所有必需的属性现在都位于单个对象中,因此处理步骤
和值
状态要容易得多
工作演示在。我很难理解您的代码,但现场演示看起来足够清晰 您的状态是一个数组,每个项都可以作为一个独立的组件呈现。您要做的是让状态向下流到组件中,并将它们连接起来以正确更新它(当您单击delete键时,需要删除一个数组项)
以下是如何以更简单的方式实现这一点:。我很难理解您的代码,但现场演示看起来足够清晰 您的状态是一个数组,每个项都可以作为一个独立的组件呈现。您要做的是让状态向下流到组件中,并将它们连接起来以正确更新它(当您单击delete键时,需要删除一个数组项)
以下是如何以更简单的方式实现这一点:。为每个组件指定一个唯一的标识符。删除组件时,请按id查找它并从阵列中删除。不要使用索引,因为它不是持久的给每个组件一个唯一的标识符。删除组件时,请按id查找它并从阵列中删除。不要使用索引,因为它不是持久的添加ID有效!非常感谢。不客气。添加ID有效!非常感谢。不客气。因为您的项目组件没有任何内部状态,所以我报告的错误不会发生。即使是上面我标记为正确的解决方案也忽略了一个事实,即分配给组件的键(在您的示例中为Item)不应该包含索引。它需要一个唯一的id。@LBecker我不确定我是否明白。传递组件渲染自身所需的道具有什么问题?传递道具没有什么问题。但是,当道具更改时,组件在状态中保持的值并不总是保持不变。这就是为什么我说您的项目组件没有反映我看到的问题。项在状态(useState)中没有任何内容。Alpha生成一个随机数并将其存储在状态中,以演示当索引1第一次被删除时,该值如何不会成为索引1的新值,而原始索引2成为索引1。@LBecker但是您真的需要在
Alpha
/项
组件中保持状态吗?在我看来,这只是增加了不必要的复杂性。因为您的项目组件没有任何内部状态,所以我报告的错误不会发生。即使是上面我标记为正确的解决方案也忽略了一个事实,即分配给组件的键(在您的示例中为Item)不应该包含索引。它需要一个唯一的id。@LBecker我不确定我是否明白。传递组件渲染自身所需的道具有什么问题?传递道具没有什么问题。但是,当道具更改时,组件在状态中保持的值并不总是保持不变。这就是为什么我说您的项目组件没有反映我看到的问题。项在状态(useState)中没有任何内容。Alpha生成一个随机数并将其存储在状态中,以演示当索引1第一次被删除时,该值如何不会成为索引1的新值,而原始索引2成为索引1。@LBecker但是您真的需要在Alpha
/项
组件中保持状态吗?在我看来,这只是增加了不必要的复杂性。