【问题标题】:How to remove a component React has rendered via a function如何删除 React 通过函数呈现的组件
【发布时间】:2021-04-08 20:32:30
【问题描述】:

请参考this Codesandbox for my example.

我在删除通过函数呈现的组件时遇到问题。由于组件不应该存储在状态中,因此我将它们的类型存储在父组件状态的数组中。一个函数遍历该数组以呈现组件。当我尝试按索引删除特定组件时,React 不会更新我要保留的组件中的道具(索引)(即:将索引 2 处的组件更改为索引 1)。相反,它会在该索引处呈现组件。我的 Codesandbox 示例演示了这种行为。

如何删除以这种方式呈现的组件(通过使用父状态填充道具的函数)?有没有其他方法可以渲染这些组件?

【问题讨论】:

  • 给每个组件一个唯一的标识符。当你删除一个组件时,通过 id 找到它并从数组中移除。不要使用索引,因为它不是持久的

标签: reactjs


【解决方案1】:

就像@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));
  };

由于您所有需要的属性现在都在单个对象中,因此处理stepsvalues 状态要容易得多。

工作演示CodeSandbox

【讨论】:

    【解决方案2】:

    我有点难以理解您的代码,但现场演示看起来足够清晰。

    您的状态是一个数组,每个项目都可以呈现为一个独立的组件。您要做的是让状态向下流入您的组件,并将它们连接起来以正确更新它(当您单击删除键时,需要删除一个数组项)。

    您可以通过以下方式以更简单的方式实现此目的:CodeSandbox demo

    【讨论】:

    • 由于您的 Item 组件没有任何内部状态,因此不会发生我报告的错误。即使上面我标记为正确的解决方案也错过了分配给组件(在您的情况下为 Item)的键不应该包含索引的事实。它需要一个唯一的 ID。
    • @LBecker 我不确定我是否遵循。传递组件需要渲染自身的 props 有什么问题?
    • 传递道具没有错。然而,当 props 改变时,组件在 state 中保存的值并不总是保持不变。这就是为什么我说您的 Item 组件没有反映我所看到的问题。项目在状态 (useState) 中没有任何内容。 Alpha 生成一个随机数并将其存储在 state 中,以演示当第一次删除索引 1 并且原始索引 2 变为索引 1 时该值不会成为索引 1 的新值。
    • @LBecker 但是你真的需要在Alpha/Item 组件中维护状态吗?在我看来,这只是增加了不必要的复杂性。
    猜你喜欢
    • 2023-02-22
    • 2018-04-27
    • 2021-08-10
    • 1970-01-01
    • 2022-01-22
    • 2021-11-27
    • 2018-01-08
    • 2019-09-22
    • 2020-07-03
    相关资源
    最近更新 更多