antd v4 - 步骤和表单

问题描述 投票:0回答:3

我是 React 新手,正在尝试 ant design。我需要构建一个多步骤表单,其中每个步骤都有几个字段,最后一步将有一个提交按钮。这将使用 antd 的 useForm 钩子。我不想使用任何其他插件,例如 antd-form-builder 等。

我面临的问题是,在多步骤表单中,在最后一步,当我按提交时,最后一步的表单数据可用,而先前步骤的数据不可用。我认为这可能是因为当我移动到“下一步”时,该步骤在 DOM 中被替换。

有没有更简单的方法来获取最后一步所有表单的数据?

我已经为示例准备了一个codesandbox。提交后请参阅控制台。

https://codesandbox.io/s/cool-mcnulty-or8jw

感谢您的帮助!

reactjs antd
3个回答
18
投票

虽然上面的答案有效,但我不喜欢使用 CSS 来隐藏和显示步骤,因为它违背了 React 仅渲染所需组件的目的。

Antd 实际上在其文档中有一个内置的方法来处理这个问题。您所需要做的就是更新以下代码。

const formData = form.getFieldsValue();

const formData = form.getFieldsValue(true);

这将返回所有字段的值,而不仅仅是隐藏字段的值,请参阅其文档:https://ant.design/components/form/#API;


12
投票

是的,这是因为当你没有在 DOM 中显示步骤时,你的步骤就会被破坏。

将步骤添加到步骤数组中,如下所示:

const steps = [
    {
      step: 1,
      title: "Step1",
      content: <Step1Form />
    },
    {
      step: 2,
      title: "Step2",
      content: <Step2Form />
    }
];

然后在你的css文件中定义一个新类:

.hidden { display: none; }

最后,在您的

StepPanel.js
文件中更改步骤的渲染方法。我们将渲染所有步骤:

{props.steps.map((item) => (
    <div
      className={`steps-content ${
        item.step !== activeStep + 1 && "hidden"
      }`}
    >
      {item.content}
    </div>
))}

如您所见,我们正在检查每个步骤的步骤编号是否等于当前活动步骤。您可以在此处更改沙箱的分叉版本。


0
投票

感谢所有答案这个这个 我从中受益匪浅,并通过更新的 9-2024 和 antd 5.20 增强了答案

主要思想是 在主组件中添加表单,并在其他组件中单独添加表单列表

首先,为步进器和内容创建 2 个列表

const Page = () => {
//mainForm.tsx
//create 2 lists for stepper and content
   const items: StepsProps["items"] = [
    {
      title: "First",
    },
    {
      title: "Second",
    },
    {
      title: "Last",
    },
   ];

   const stepperItems = [
     {
     title: "First",
     content: <DescriptionServiceForm />,
    },
    {
     title: "Second",
     content: <PriceAndAddons />,
    },
    {
     title: "Last",
    content: "Last-content",
    },
   ];

  const [form] = Form.useForm();
  const [current, setCurrent] = useState(0);
//if you want to save form values in useState or you can use form.getFieldsValue(true)
  const [formValues, setFormValues] = useState<any>({});

  const next = () => {
 //use this to return all form lists
     const values = form.getFieldsValue(true);
//or this to return every form list alone and store it in state
     const values = form.getFieldsValue();
     setFormValues((prev: any) => ({ ...prev, ...values }));

     setCurrent(current + 1);
  };

const prev = () => {
  setCurrent(current - 1);
};
return (
  <Form form={form}>
      <Steps
        size="small"
        current={0}
        items={items}
      />
      <div>
        {stepperItems[current].content}
        {current < stepperItems.length - 1 && (
          <Button type="primary" onClick={() => next()}>
            Next
          </Button>
        )}
        {current === stepperItems.length - 1 && (
          <Button type="primary">
            Done
          </Button>
        )}
        {current > 0 && (
          <Button onClick={() => prev()}>
            Previous
          </Button>
        )}
      </div>
    </Form>
)};
export default Page;

实现表单的第 1 部分,以在第一步中将其显示为活动状态

const DescriptionServiceForm = () => {
   return (
    <Form.List name="description">
      {(fields, operation, meta) => (
      <div className="flex gap-5 w-full">
        <Form.Item
          label="firstName"
          name="first_name"
        >
          <Input />
        </Form.Item>
        <Form.Item 
          label="lastName"
          name="last_name"
        >
          <Input />
        </Form.Item>
      </div>
    )}
  </Form.List>
)}
export default DescriptionServiceForm;

实现表单的第 2 部分,以在第二步中将其显示为活动状态

const PriceAndAddons = () => {
   return (
    <Form.List name="description">
      {(fields, operation, meta) => (
      <div className="flex gap-5 w-full">
        <Form.Item
          label="email"
          name="email"
        >
          <Input />
        </Form.Item>
      </div>
    )}
  </Form.List>
)}
export default PriceAndAddons;

最终输出将表单的每个部分分类到一个以 formList 名称命名的对象中

values = {
"description": {
    "first_name": "Ahmed",
    "last_name": "Korany"
},
"priceAndAddons": {
    "email": "[email protected]"
}

}

© www.soinside.com 2019 - 2024. All rights reserved.