You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AntD Modal内嵌Steps无法获取第二步Form数据问题

AntD Modal内Steps嵌入多Form无法获取第二步Form数据的解决方案

问题现象

在AntD Modal组件的Steps中嵌入两个独立Form,每个Form都创建了独立的useForm实例并单独校验,但无法获取第二步Form的数据。将该Form移至第一步时可正常获取数据,推测是Steps加载时的hydration(水合)问题。原代码如下:

import { React, FC } from "react";

const Form = () => {
  const [Form1] = useForm();
  const [Form2] = useForm();

  const checkFormValidations = async () => {
    try {
      const data = await realtorForm1.validateFields();
      next();
    } catch (e) {
      message.error(e.message.data);
    }
  };

  const checkForm2Validations = async () => {
    try {
      const data = await realtorForm2.validateFields();
      // I am not getting this data
      // Calling API to Add Data
    } catch (e) {
      message.error(e.message.data);
    }
  };

  const steps = [
    {
      key: 1,
      title: "First",
      content: (
        <Form
          form={Form1}
          initialValues={DataProps}
          validateTrigger="onBlur"
        ></Form>
      ),
    },
    {
      key: 2,
      title: "Second",
      content: (
        <Form
          form={Form2}
          initialValues={DataProps}
          validateTrigger="onBlur"
        ></Form>
      ),
    },
  ];

  return (
    <Modal>
      <Steps current={current} items={items} />
      <div style={contentStyle}>{steps[current].content}</div>
      <div style={{ display: "flex" }}>
        {current < steps.length - 1 && (
          <BaseButton type="primary" onClick={() => checkFormValidations()}>
            Next
          </BaseButton>
        )}
        {current > 0 && (
          <BaseButton style={{ margin: "0 8px" }} onClick={() => prev()}>
            Previous
          </BaseButton>
        )}
        {current === steps.length - 1 && (
          <BaseButton type="primary" onClick={() => checkForm2Validations()}>
            Submit
          </BaseButton>
        )}
      </div>
    </Modal>
  );
};

问题原因

  1. 变量名不一致:校验方法中使用realtorForm1/realtorForm2,但实际定义的实例是Form1/Form2,直接导致调用失败。
  2. 组件命名冲突:自定义组件名为Form,与AntD的Form组件重名,React无法正确识别AntD Form。
  3. 预渲染导致实例失效:两个Form提前写在steps数组中初始化时会被预渲染,非当前步骤的Form会被卸载,导致useForm实例与DOM元素解绑,切换到第二步时实例无法同步更新。

解决方案

1. 修正命名问题

  • 将自定义组件名改为MultiStepForm,避免与AntD Form重名;
  • 统一useForm实例的变量名,确保校验时调用正确实例。

2. 动态渲染Form

通过条件渲染确保只有当前步骤的Form被挂载,避免预渲染导致的实例失效。

修正后的完整代码

import React, { useState } from "react";
import { Modal, Steps, Form as AntdForm, Button, message } from "antd";

const MultiStepForm = () => {
  const [currentStep, setCurrentStep] = useState(0);
  const [form1] = AntdForm.useForm();
  const [form2] = AntdForm.useForm();

  const nextStep = () => {
    setCurrentStep(prev => prev + 1);
  };

  const prevStep = () => {
    setCurrentStep(prev => prev - 1);
  };

  const checkForm1Validations = async () => {
    try {
      const data = await form1.validateFields();
      console.log("第一步数据:", data);
      nextStep();
    } catch (e) {
      message.error(e.message || "表单校验失败");
    }
  };

  const checkForm2Validations = async () => {
    try {
      const data = await form2.validateFields();
      console.log("第二步数据:", data);
      // 调用API提交数据
      message.success("提交成功");
    } catch (e) {
      message.error(e.message || "表单校验失败");
    }
  };

  const steps = [
    { key: "1", title: "第一步" },
    { key: "2", title: "第二步" },
  ];

  const contentStyle = { padding: "24px 0" };

  return (
    <Modal title="多步骤表单" open={true} footer={null}>
      <Steps current={currentStep} items={steps} />
      <div style={contentStyle}>
        {currentStep === 0 && (
          <AntdForm
            form={form1}
            initialValues={{ name: "", email: "" }}
            validateTrigger="onBlur"
          >
            <AntdForm.Item
              name="name"
              label="姓名"
              rules={[{ required: true, message: "请输入姓名" }]}
            >
              <input placeholder="请输入姓名" />
            </AntdForm.Item>
            <AntdForm.Item
              name="email"
              label="邮箱"
              rules={[{ required: true, type: "email", message: "请输入正确的邮箱" }]}
            >
              <input placeholder="请输入邮箱" />
            </AntdForm.Item>
          </AntdForm>
        )}
        {currentStep === 1 && (
          <AntdForm
            form={form2}
            initialValues={{ phone: "", address: "" }}
            validateTrigger="onBlur"
          >
            <AntdForm.Item
              name="phone"
              label="手机号"
              rules={[{ required: true, message: "请输入手机号" }]}
            >
              <input placeholder="请输入手机号" />
            </AntdForm.Item>
            <AntdForm.Item
              name="address"
              label="地址"
              rules={[{ required: true, message: "请输入地址" }]}
            >
              <input placeholder="请输入地址" />
            </AntdForm.Item>
          </AntdForm>
        )}
      </div>
      <div style={{ display: "flex" }}>
        {currentStep < steps.length - 1 && (
          <Button type="primary" onClick={checkForm1Validations}>
            下一步
          </Button>
        )}
        {currentStep > 0 && (
          <Button style={{ margin: "0 8px" }} onClick={prevStep}>
            上一步
          </Button>
        )}
        {currentStep === steps.length - 1 && (
          <Button type="primary" onClick={checkForm2Validations}>
            提交
          </Button>
        )}
      </div>
    </Modal>
  );
};

export default MultiStepForm;

关键优化点

  • 通过currentStep条件渲染,仅挂载当前步骤的Form,避免实例与DOM解绑;
  • 修正了变量名冲突和调用错误;
  • 完善了步骤切换的状态管理逻辑。

内容的提问来源于stack exchange,提问作者Rahul Rajan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 13:34:55