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

如何在两个Yup Schema之间共享字段值(多步骤表单场景)

多步骤表单跨步骤字段验证实现(React Hook Form + Yup)

问题场景

正在构建多步骤表单,每个步骤为独立表单并拥有各自的验证Schema,使用React Hook Form处理表单、Yup做验证。需求是在page2的Schema中获取步骤1的signature字段值,仅当该字段满足特定条件时,将page2的dependentField设为必填项。原代码示例如下:

export const page1Schema = yup.object().shape({
  ["signature"]: yup.string().required(),
});

export const page2Schema = yup.object().shape({
  ["dependentField"]: yup.string().when(["signature"], {
    is: (signature) => signature !== "",
    then: () => yup.string().required(),
    otherwise: () => yup.string().notRequired(),
  })
});

实现方案

因为每个步骤是独立表单,page2的Schema无法直接访问page1的字段值,需要通过跨步骤共享数据+动态生成Schema来实现,以下是两种可行方式:

方式一:动态生成Schema(推荐)

  1. 存储page1的字段值:在父组件或全局状态(如useState、Context)中保存page1提交后的signature值。
// 父组件示例
import { useState } from 'react';

const MultiStepForm = () => {
  const [page1Data, setPage1Data] = useState({});

  // page1表单提交时保存数据
  const handlePage1Submit = (data) => {
    setPage1Data(data);
    // 跳转至page2的逻辑
  };

  return (
    // 步骤切换逻辑,传递page1Data给page2组件
  );
};
  1. 将page2Schema改为参数化函数:接收signature作为参数,动态生成验证规则。
export const getPage2Schema = (signature) => yup.object().shape({
  dependentField: yup.string().when([], {
    is: () => signature !== "",
    then: () => yup.string().required("此字段为必填项"),
    otherwise: () => yup.string().notRequired(),
  })
});
  1. 在page2组件中使用动态Schema:
import { useForm } from 'react-hook-form';
import { yupResolver } from '@hookform/resolvers/yup';
import { getPage2Schema } from './schemas';

const Page2 = ({ page1Data }) => {
  const page2Schema = getPage2Schema(page1Data.signature);
  const { register, handleSubmit, formState: { errors } } = useForm({
    resolver: yupResolver(page2Schema)
  });

  return (
    <form onSubmit={handleSubmit(/* 提交逻辑 */)}>
      <input {...register("dependentField")} />
      {errors.dependentField && <p>{errors.dependentField.message}</p>}
      {/* 其他表单元素 */}
    </form>
  );
};

方式二:在page2中添加隐藏字段

如果需要保留Yup原有的when语法,可以将page1的signature作为隐藏字段加入page2表单,让Yup能直接读取该值:

  1. 在page2表单中添加隐藏字段:
// Page2组件内
<input 
  type="hidden" 
  {...register("signature")} 
  defaultValue={page1Data.signature} 
/>
  1. 修改page2Schema:新增signature字段定义,确保Yup能识别该字段:
export const page2Schema = yup.object().shape({
  signature: yup.string(), // 定义字段,避免Yup验证报错
  dependentField: yup.string().when(["signature"], {
    is: (signature) => signature !== "",
    then: () => yup.string().required("此字段为必填项"),
    otherwise: () => yup.string().notRequired(),
  })
});

方案对比

  • 方式一(动态Schema):逻辑清晰,无需冗余字段,适合多步骤表单数据单向流动的场景。
  • 方式二(隐藏字段):保留了Yupwhen的原生写法,适合需要在page2中修改前置字段值的特殊场景(多步骤表单中较少见)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 09:57:21