首页 > 解决方案 > 如何在反应表单中创建同一字段的多个实例

问题描述

嗨,我想创建一个这样的表单集:

在此处输入图像描述

如果我单击添加一个,它会添加一个。如果我按 x,它会删除一个。

我怎样才能在formik中产生这个?有什么简单的方法吗?

标签: reactjsformik

解决方案


在我看来,我会使用useFormik钩子,我认为这个钩子很容易理解。

(最终代码放在最后)

首先:声明 initialValues 具有这样的数组字段并且它应该具有唯一的 id,因为如果您在 map 时使用索引作为键,有时反应将无法正确呈现。在这个例子中,我使用uuid

const formik = useFormik({
  initialValues: {
    contacts: [
      {
        id: uuid(),
        name: "",
        email: "",
      },
    ],
  }
});

然后:我将创建 2 个函数来添加句柄和删除句柄

const handleAddField = () => {
  formik.setFieldValue("contacts", [
    ...formik.values.contacts,
    { id: uuid(), name: "", email: "" },
  ]);
};

const handleRemoveField = (id) => {
  formik.setFieldValue(
    "contacts",
    formik.values.contacts.filter((contact) => contact.id !== id)
  );
};

最后:只需像这样用地图渲染它

<form onSubmit={formik.handleSubmit}>
  {formik.values.contacts.map((contact, index) => (
    <div key={contact.id}>
      <label>Name</label>
      <input {...formik.getFieldProps(`contacts[${index}].name`)} />
      <label>Email</label>
      <input {...formik.getFieldProps(`contacts[${index}].email`)} />
      <button type="button" onClick={() => handleRemoveField(contact.id)}>
        Delete
      </button>
    </div>
  ))}
  <button type="submit">Submit</button>
  <button type="button" onClick={handleNewField}>
    Add Field
  </button>
</form>

最终代码如下所示 - 这是一个代码框

import React from "react";
import { v4 as uuid } from "uuid";
import { useFormik } from "formik";

function App() {
  const formik = useFormik({
    initialValues: {
      contacts: [
        {
          id: uuid(),
          name: "",
          email: "",
        },
      ],
    },
    onSubmit: (values) => {
      console.log(values);
    },
  });

  const handleNewField = () => {
    formik.setFieldValue("contacts", [
      ...formik.values.contacts,
      { id: uuid(), name: "", email: "" },
    ]);
  };

  const handleRemoveField = (id) => {
    formik.setFieldValue(
      "contacts",
      formik.values.contacts.filter((contact) => contact.id !== id)
    );
  };

  return (
    <div>
      <form onSubmit={formik.handleSubmit}>
        {formik.values.contacts.map((contact, index) => (
          <div key={contact.id}>
            <label>Name</label>
            <input {...formik.getFieldProps(`contacts[${index}].name`)} />
            <label>Email</label>
            <input {...formik.getFieldProps(`contacts[${index}].email`)} />
            <button type="button" onClick={() => handleRemoveField(contact.id)}>
              Delete
            </button>
          </div>
        ))}
        <button type="submit">Submit</button>
        <button type="button" onClick={handleNewField}>
          Add Field
        </button>
      </form>
    </div>
  );
}

export default App;

推荐阅读