首页 > 解决方案 > 用 antd 反应动态表单值

问题描述

带有 react 和 antd 的动态表单让我望而却步。我在网上搜索了寻找答案无济于事。这是一个代码笔,可以解决我遇到的问题:https ://codepen.io/sethen/pen/RwrrmVw

从本质上讲,问题归结为当您想要遍历存储在状态中的一堆值时,如下所示:

class MyClass extends React.Component<{}, {}> {
  constructor(props) {
    super(props);

    this.state = {
      data: [
        { name: 'foo' },
        { name: 'bar' },
        { name: 'baz' }
      ]
    };
  }

您可以将这些值视为从某个远程 API 获取的。

如您所见,我有一个name状态为键的对象数组。在渲染周期中进一步向下是以下内容:

return data.map((value, index) => {
      const { name } = value;

      return (
        <Form key={ index } initialValues={ { name } }>
          <Form.Item name='name'>
            <Input type='text' />
          </Form.Item>

          <Button onClick={ this.handleOnDeleteClick.bind(this, index) }>Delete</Button>
        </Form>
      );

这会尝试遍历存储在状态中的值并将这些值放入输入中。它还添加了一个小删除按钮来删除该项目。第一次渲染时,它会按照您的预期将值加载到输入值中。

问题是当您尝试删除其中一项时,例如中间一项,它将删除下一项。问题的核心是渲染的行为与我在删除项目时的预期不同。我期望当我删除一个项目时,它会使其脱离状态并加载剩下的项目。这没有发生。

我的问题是,我如何能够以这种方式使用 antd 加载动态数据,同时能够删除每个项目?

标签: javascriptreactjstypescriptantd

解决方案


这种形式的主要错误是将属性分配key数组索引,并且在删除中间项时,最后一个组件将获得一个新键

在 React 中,更改密钥将卸载组件并丢失其状态。

不要将类似的东西传递Math.random()给键。重要的是,键在重新渲染时具有“稳定的身份”,以便 React 可以确定何时添加、删除或重新排序项目。理想情况下,密钥应对应于来自您的数据的唯一且稳定的标识符,例如post.id.

此外,在您的示例中,您实际上呈现了三个表单,而不是一个表单和三个字段。

每个<form/>在其内部状态中都有其表单字段的所有状态,因此您将拥有一个包含所有input值的对象。

Antd.Form只是这样的包装器,例如form,您可以在回调中获取Form.Item值。onFinish

class MyClass extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      data: [{ name: "foo" }, { name: "bar" }, { name: "baz" }]
    };
  }

  handleOnDeleteClick = index => {
    this.setState({
      data: [
        ...this.state.data.slice(0, index),
        ...this.state.data.slice(index + 1)
      ]
    });
  };

  render() {
    const { data } = this.state;

    return (
      <Form>
        {data.map(({ name }, index) => {
          return (
            <Form.Item key={name}>
              <Input type="text" />
              <Button onClick={() => this.handleOnDeleteClick(index)}>
                Delete
              </Button>
            </Form.Item>
          );
        })}
      </Form>
    );
  }
}

编辑 reverent-nash-dlqxb


推荐阅读