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

React中StepZilla表单向导的校验与API提交实现求助

解决StepZilla表单向导的表单校验与API提交问题

一、统一管理表单数据

StepZilla不内置表单状态管理,需在父组件维护全局表单状态,通过props传递给子步骤组件,并提供数据更新回调。

父组件示例代码

import React, { useState } from 'react';
import StepZilla from 'react-stepzilla';

import Step1 from './Step1';
import Step2 from './Step2';
import Step3 from './Step3';

const App = () => {
  const [formData, setFormData] = useState({
    step1: { name: '', email: '' },
    step2: { phone: '', address: '' },
    step3: { paymentMethod: '', cardNumber: '' }
  });

  const updateFormData = (step, field, value) => {
    setFormData(prev => ({
      ...prev,
      [step]: {
        ...prev[step],
        [field]: value
      }
    }));
  };

  const steps = [
    { name: '基本信息', component: <Step1 formData={formData.step1} updateFormData={updateFormData} /> },
    { name: '联系方式', component: <Step2 formData={formData.step2} updateFormData={updateFormData} /> },
    { name: '支付信息', component: <Step3 formData={formData.step3} updateFormData={updateFormData} /> }
  ];

  return (
    <div className="step-progress">
      <StepZilla steps={steps} showNavigation={true} />
    </div>
  );
};

export default App;

子步骤组件示例(以Step1为例)

import React from 'react';

const Step1 = ({ formData, updateFormData }) => {
  return (
    <div className="step-container">
      <div>
        <label>姓名:</label>
        <input
          type="text"
          value={formData.name}
          onChange={(e) => updateFormData('step1', 'name', e.target.value)}
        />
      </div>
      <div>
        <label>邮箱:</label>
        <input
          type="email"
          value={formData.email}
          onChange={(e) => updateFormData('step1', 'email', e.target.value)}
        />
      </div>
    </div>
  );
};

export default Step1;

二、实现表单校验

1. 单步骤切换前校验

利用StepZilla的onStepChange回调,在切换步骤前校验当前步骤字段,不通过则阻止切换。

修改父组件,添加校验逻辑:

const validateStep = (stepIndex) => {
  switch(stepIndex) {
    case 0: // Step1校验
      const { name, email } = formData.step1;
      if (!name.trim()) {
        alert('请输入姓名');
        return false;
      }
      if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
        alert('请输入有效的邮箱');
        return false;
      }
      return true;
    case 1: // Step2校验
      const { phone } = formData.step2;
      if (!/^1[3-9]\d{9}$/.test(phone)) {
        alert('请输入有效的手机号');
        return false;
      }
      return true;
    default:
      return true;
  }
};

// 更新StepZilla配置
<StepZilla 
  steps={steps} 
  showNavigation={true}
  onStepChange={(nextStepIndex, prevStepIndex) => {
    if (prevStepIndex > -1) {
      return validateStep(prevStepIndex);
    }
    return true;
  }}
/>

2. 最终提交前全局校验

若需在最后一步完成后统一校验所有字段,可编写全局校验函数:

const validateAll = () => {
  let isValid = true;
  // 校验Step1
  if (!formData.step1.name.trim() || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(formData.step1.email)) {
    alert('基本信息填写不完整或格式错误');
    isValid = false;
  }
  // 校验Step2
  if (!/^1[3-9]\d{9}$/.test(formData.step2.phone)) {
    alert('手机号格式错误');
    isValid = false;
  }
  // 校验Step3
  if (!formData.step3.paymentMethod || !formData.step3.cardNumber.trim()) {
    alert('支付信息填写不完整');
    isValid = false;
  }
  return isValid;
};

三、实现API提交

方法1:最后一步添加提交按钮

在父组件添加提交函数,并传递给最后一步组件:

const submitForm = async () => {
  if (!validateAll()) return;
  
  try {
    const response = await fetch('你的API接口地址', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(formData),
    });
    
    if (response.ok) {
      alert('提交成功');
      // 重置表单
      setFormData({
        step1: { name: '', email: '' },
        step2: { phone: '', address: '' },
        step3: { paymentMethod: '', cardNumber: '' }
      });
    } else {
      throw new Error('提交失败');
    }
  } catch (error) {
    alert(`提交出错:${error.message}`);
  }
};

// 更新Step3的配置
{ name: '支付信息', component: <Step3 formData={formData.step3} updateFormData={updateFormData} submitForm={submitForm} /> }

Step3组件添加提交按钮:

import React from 'react';

const Step3 = ({ formData, updateFormData, submitForm }) => {
  return (
    <div className="step-container">
      <div>
        <label>支付方式:</label>
        <select
          value={formData.paymentMethod}
          onChange={(e) => updateFormData('step3', 'paymentMethod', e.target.value)}
        >
          <option value="">请选择</option>
          <option value="credit">信用卡</option>
          <option value="alipay">支付宝</option>
        </select>
      </div>
      <div>
        <label>卡号:</label>
        <input
          type="text"
          value={formData.cardNumber}
          onChange={(e) => updateFormData('step3', 'cardNumber', e.target.value)}
        />
      </div>
      <button onClick={submitForm}>提交表单</button>
    </div>
  );
};

export default Step3;

方法2:使用onAllStepsComplete回调

在StepZilla中配置该回调,所有步骤完成时自动触发提交:

<StepZilla 
  steps={steps} 
  showNavigation={true}
  onStepChange={(nextStepIndex, prevStepIndex) => {
    if (prevStepIndex > -1) {
      return validateStep(prevStepIndex);
    }
    return true;
  }}
  onAllStepsComplete={() => {
    submitForm();
    return false; // 返回false阻止默认步骤重置,按需调整
  }}
/>

注意事项

  • 复杂校验场景推荐使用Yup或Zod等Schema校验库,提升代码可维护性。
  • API提交时需处理跨域问题,可通过后端配置CORS或前端设置代理解决。
  • 提交过程中可添加加载状态,禁用按钮避免重复提交。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 17:25:30