基于Formik与Yup的多步骤表单填写后自动跳转下一步方案咨询
Formik+Yup多步骤表单自动跳转实现方案
核心实现思路
- 基于校验状态的变更监听
利用Formik内置的useFormikContext钩子可以全局拿到表单的values(字段值)、errors(校验错误)、touched(字段是否被修改过)三个核心状态,配合useEffect监听当前步骤关联的字段变更,每次变更后用对应步骤的Yup校验Schema做全量校验,只要当前步骤所有必填字段都通过校验、且都被用户修改过,就触发下一步跳转。
参考实现代码:
把上面的import { useEffect } from 'react'; import { useFormikContext } from 'formik'; import * as Yup from 'yup'; // 按步骤定义的Yup校验规则 const stepValidationSchemas = [ // 第1步校验规则 Yup.object({ username: Yup.string().min(2, '最少2位').required('必填项'), }), // 第2步校验规则 Yup.object({ phone: Yup.string().matches(/^1[3-9]\d{9}$/, '手机号格式错误').required('必填项'), }) ]; function StepAutoJump({ currentStep, goNext }) { const { values, touched } = useFormikContext(); const currentSchema = stepValidationSchemas[currentStep]; useEffect(() => { // 校验当前步骤所有字段 currentSchema.validate(values, { abortEarly: false }) .then(() => { // 校验通过后判断所有字段是否都被用户触摸过 const stepFields = Object.keys(currentSchema.fields); const allFieldsTouched = stepFields.every(field => touched[field]); if (allFieldsTouched) { // 加防抖避免频繁触发 const timer = setTimeout(() => goNext(), 300); return () => clearTimeout(timer); } }) .catch(() => { // 校验不通过时不做跳转操作 }); }, [values, touched, currentSchema, goNext]); return null; }<StepAutoJump />组件放到每个步骤的表单组件里即可生效。 - 单字段步骤简化实现
如果每个步骤只有一个输入字段,可以直接在字段的onChange或onBlur回调里加跳转判断,不需要全局监听,性能更高:<input name="email" onBlur={(e) => { formik.handleBlur(e); // 等待Formik状态更新后判断 setTimeout(() => { if (!formik.errors.email && formik.touched.email) { goNextStep(); } }, 100); }} />
注意事项
- 必须加防抖/延迟逻辑,避免用户输入到一半还没完成就触发跳转,影响使用体验。
- 增加跳转锁状态,避免同一个步骤重复触发多次跳转逻辑,导致步骤错乱。
- 如果当前步骤存在非必填字段,需要调整校验判断逻辑,避免用户没填可选字段时无法跳转。
学习参考
可以直接查阅Formik官方文档中useFormikContext、自定义钩子相关章节,以及Yup官方文档的校验方法说明,就能覆盖所有相关用法。
内容的提问来源于stack exchange,提问作者Ahmed Elbessfy
相关产品推荐
相关产品推荐

