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

如何在Ant Design+React多步骤表单中实现字段校验?

解决Ant Design多步骤表单步骤校验问题

你遇到的form未定义问题,核心原因是没有正确获取Ant Design Form组件的实例,且当前每个步骤组件都创建了独立Form,导致无法在父组件中统一执行校验逻辑。以下是具体解决方案:

步骤1:在App组件中统一创建Form实例并包裹步骤内容

将整个步骤容器用Form组件包裹,通过ref获取Form实例,实现父组件对表单校验的统一控制。

修改后的App.js代码:

import { Button, Steps, Modal, Result, Form } from "antd";
import React, { Component, createRef } from "react";
import AmountStep from "../components/AmountStep";

const { Step } = Steps;
const steps = [
  {
    title: "Amount",
    content: <AmountStep />,
    fields: ["amount"]
  },
  {
    title: "Recipient",
    content: <RecipientStep />,
    fields: ["name", "family"]
  },
  {
    title: "Verification",
    content: <Verification />
  },
  {
    title: "Review",
    content: <Review />
  }
];

class App extends Component {
  state = {
    current: 0,
  };
  // 创建Form实例的引用
  formRef = createRef();

  render() {
    return (
      <>
        {/* 用Form组件统一包裹所有步骤内容 */}
        <Form ref={this.formRef} name="multi-step-form" layout="vertical">
          <div className="steps-container">
            <Steps current={this.state.current}>
              {steps.map(item => (
                <Step key={item.title} title={item.title} />
              ))}
            </Steps>
            <div className="steps-content">
              {steps[this.state.current].content}
            </div>
            <div className="steps-action">
              {this.state.current > 0 && (
                <Button
                  style={{ margin: "0 8px" }}
                  onClick={this.prev}
                >
                  Previous
                </Button>
              )}
              {this.state.current < steps.length - 1 && (
                <Button type="primary" onClick={this.next}>
                  Next
                </Button>
              )}
              {this.state.current === steps.length - 1 && (
                <Button type="primary">
                  Confirm
                </Button>
              )}
            </div>
          </div>
        </Form>
      </>
    );
  }

  next = async () => {
    const currentStep = steps[this.state.current];
    // 若当前步骤无需校验,直接跳转
    if (!currentStep.fields) {
      this.setState({ current: this.state.current + 1 });
      return;
    }
    try {
      // 通过ref获取Form实例,仅校验当前步骤指定字段
      await this.formRef.current.validateFields(currentStep.fields);
      this.setState({ current: this.state.current + 1 });
    } catch (errorInfo) {
      console.log("校验失败:", errorInfo);
      // 此处可添加错误提示,比如使用Antd的message组件展示错误信息
    }
  };

  prev = () => {
    this.setState({ current: this.state.current - 1 });
  };
}

export { App };

步骤2:修改AmountStep组件,移除独立Form

子组件无需再创建独立Form,直接复用父组件的Form上下文即可:

修改后的AmountStep.js代码:

import { Row, InputNumber, Form } from "antd";
import "antd/dist/antd.css";
import React, { Component } from "react";

class AmountStep extends Component {
  render() {
    return (
      <>
        <Row className="form-container recipient-step">
          <h2 className="form-title">amount</h2>
          <div className="amount">
            <Form.Item
              name="amount"
              label="Amount:"
              rules={[
                {
                  required: true,
                  message: "Please input your Amount!"
                },
                {
                  min: 50,
                  message: "Amount must be at least 50!"
                }
              ]}
            >
              <InputNumber
                style={{ width: "100%" }}
                min={50}
              />
            </Form.Item>
          </div>
        </Row>
      </>
    );
  }
}

export default AmountStep;

关键说明

  • 父组件通过createRef()获取Form实例,实现对validateFields()方法的调用
  • 每个步骤的fields数组定义了当前步骤需要校验的字段,跳转时仅校验对应字段,避免全局校验
  • 子组件复用父Form上下文,表单状态统一管理,无需重复创建Form
  • 校验失败时进入catch块,可在此处添加用户友好的错误提示逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 11:24:28