使用Mantine+Yup实现多步表单 未校验通过仍跳转下一步问题
问题根因
你的判断完全正确:Next按钮的onClick回调直接执行了activeStep更新,没有触发任何当前步骤的字段校验逻辑。Mantine useForm 绑定的Yup校验默认只会在表单提交、手动调用校验API时触发,你给Next按钮同时绑定onClick跳步和type="submit"时,onClick逻辑会先执行,根本等不到校验跑完就已经切到下一步了。
修复方案
Mantine useForm 暴露了validate()方法,支持传入指定字段列表手动触发对应字段的校验,校验通过会返回true,失败会自动给对应字段绑定错误提示,完全适配你用的Yup规则。你只需要在跳步前先调用这个方法校验当前步骤字段,通过后再更新步骤状态即可,完整修复代码如下:
// 按步骤索引映射当前步骤需要校验的字段,后续新增步骤直接扩展该数组即可 const stepFieldMap = [ ['email', 'password'], // 第0步:账号信息页校验字段 ['firstName', 'lastName'] // 第1步:个人信息页校验字段 ]; // 补全全量字段的Yup校验规则,避免最后提交时漏校验 const schema = yup.object().shape({ email: yup.string().email('请输入有效的邮箱地址').required('邮箱不能为空'), password: yup.string().required('密码不能为空'), firstName: yup.string().required('名不能为空'), lastName: yup.string().required('姓不能为空') }); function MultiStepForm() { const [activeStep, setActiveStep] = useState(0); const form = useForm({ schema: yupResolver(schema), initialValues: { email: "", password: "", firstName: "", lastName: "" } }); // 下一步按钮点击逻辑 const handleNext = async () => { // 仅校验当前步骤的字段,不跑全量校验 const currentStepValid = await form.validate(stepFieldMap[activeStep]); if (currentStepValid) { setActiveStep(prev => prev + 1); } }; // 表单最终提交逻辑 const handleFormSubmit = form.onSubmit((values) => { console.log('全表单校验通过,提交数据:', values); // 这里写接口提交逻辑即可 }); const isLastStep = activeStep === stepFieldMap.length - 1; return ( <form onSubmit={handleFormSubmit}> <Paper shadow="xs" p="md"> {activeStep === 0 && ( <> <Title>账号信息</Title> <Group> <TextInput label="Email" {...form.getInputProps("email")} /> <TextInput label="Password" {...form.getInputProps("password")} /> </Group> </> )} {activeStep === 1 && ( <> <Title>个人信息</Title> <Group> <TextInput label="First name" {...form.getInputProps("firstName")} /> <TextInput label="Last name" {...form.getInputProps("lastName")} /> </Group> </> )} <Group mt="xl"> <Button onClick={() => setActiveStep(prev => prev - 1)} disabled={activeStep === 0} > 上一步 </Button> {/* 最后一步渲染提交按钮,前面步骤渲染带校验的下一步按钮 */} {isLastStep ? ( <Button type="submit">提交</Button> ) : ( <Button onClick={handleNext}>下一步</Button> )} </Group> </Paper> </form> ); }
核心改动点
- 移除了Next按钮上同时绑定的
onClick直接跳步和type="submit"的冲突逻辑,避免跳步优先级高于校验 - 新增步骤字段映射表,后续扩展多步时只需要往数组里加对应字段列表即可,不需要修改核心校验逻辑
- 非最后一步点击Next时,调用
form.validate(当前步骤字段列表)异步校验当前字段,校验通过才更新步骤状态,校验失败会自动在对应输入框下方展示Yup配置的错误提示 - 补全了个人信息步骤两个字段的Yup校验规则,避免最后提交时出现未校验的字段
- 最后一步单独渲染提交按钮,触发全表单校验后执行提交逻辑
内容的提问来源于stack exchange,提问作者smartish
相关产品推荐
相关产品推荐

