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

Ant Design Steps跳转下一步前自动提交内部Form表单的实现方案咨询

实现方案

核心思路是获取第一步内嵌Form组件的实例,在点击下一步按钮时先触发表单校验/提交,校验通过后再执行步骤跳转逻辑,以下是AntD官方推荐的函数组件实现方案(更适配Form.useFormAPI,写法更简洁):

改造步骤

  1. 父组件通过useRef存储第一步Form的实例引用
  2. 第一步组件用React.forwardRef包裹,通过useImperativeHandle将内部的form实例暴露给父组件
  3. 改造下一步按钮的点击逻辑:先调用form实例的校验方法,校验成功后再跳转到下一个步骤

完整代码示例

import React, { useRef, useState, useImperativeHandle, forwardRef } from "react";
import "./App.css";
import { Form, Input, Steps, Button, message } from "antd";
import type { FormInstance } from "antd/es/form";

const { Step } = Steps;

// 定义第一步组件暴露的方法类型
interface FirstStepRef {
  form: FormInstance;
}

const FirstStep = forwardRef<FirstStepRef>((props, ref) => {
  const [form] = Form.useForm();
  // 向父组件暴露form实例
  useImperativeHandle(ref, () => ({
    form
  }));

  const onFinish = (values: any) => {
    console.log('第一步表单提交数据:', values);
    // 这里可以写第一步表单提交的业务逻辑
  };

  return (
    <Form 
      name="basic" 
      form={form} 
      onFinish={onFinish}
    >
      <Form.Item 
        label="输入项" 
        name="Input"
        rules={[{ required: true, message: '该项为必填项' }]}
      >
        <Input />
      </Form.Item>
    </Form>
  );
});

const SecondStep = () => {
  return <p> Second Step </p>;
};

const App = () => {
  const [current, setCurrent] = useState(0);
  // 存储第一步组件的ref
  const firstStepRef = useRef<FirstStepRef>(null);

  const next = async () => {
    if (current === 0) {
      try {
        // 先校验第一步表单,校验成功会返回表单数据
        const values = await firstStepRef.current?.form.validateFields();
        console.log('校验通过,表单数据:', values);
        // 如果需要触发Form的onFinish回调,可替换为:await firstStepRef.current?.form.submit();
        // 校验通过再跳步
        setCurrent(current + 1);
      } catch (error) {
        // 校验失败直接终止,AntD会自动展示错误提示
        console.log('表单校验失败:', error);
      }
      return;
    }
    setCurrent(current + 1);
  };

  const prev = () => {
    setCurrent(current - 1);
  };

  const steps = [
    {
      title: "第一步",
      content: <FirstStep ref={firstStepRef} />,
      controls: (
        <Button type="primary" onClick={next}>
          进入第二步
        </Button>
      ),
    },
    {
      title: "第二步",
      content: <SecondStep />,
      controls: (
        <>
          <Button style={{ margin: "0 8px" }} onClick={prev}>
            返回第一步
          </Button>
          <Button
            type="primary"
            onClick={() => message.success("处理完成!")}
          >
            完成
          </Button>
        </>
      ),
    },
  ];

  return (
    <>
      <Steps current={current}>
        {steps.map((item) => (
          <Step key={item.title} title={item.title} />
        ))}
      </Steps>
      <div className="steps-content">{steps[current].content}</div>
      <div className="steps-action">{steps[current].controls}</div>
    </>
  );
};

export default App;

类组件兼容方案

如果需要保留原有类组件的写法,可通过React.createRef获取第一步组件的实例,结合AntD的Form.create高阶组件获取form实例:

  • 用Form.create()(FirstStep)包裹第一步组件,form实例会被注入到this.props.form中
  • 父组件创建firstStepRef = React.createRef(),挂载到<FirstStep ref={this.firstStepRef} />
  • 点击下一步时调用this.firstStepRef.current.props.form.validateFields()执行校验逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 21:39:03