如何在Ionic React中用Yup Resolvers解决IonCheckbox布尔校验报错
问题根因
- IonCheckbox是Ionic基于Web Components封装的自定义组件,并非原生HTML输入元素。直接通过
{...register("字段名")}绑定时,React Hook Form 默认逻辑会读取事件对象的target.value属性,也就是原生复选框固定返回的字符串"on",完全无法获取组件实际的checked布尔值,因此触发Yup的类型校验报错。 - 代码中额外通过
useState维护的勾选状态,和RHF内部管理的表单状态完全独立,会出现状态不同步问题。
适配方案
1. 重构RHF配置
移除代码中checkedTermsOfUse、checkedPrivacyPolicy两个冗余的本地状态变量,所有表单状态统一交由RHF管理。从useForm中新增解构setValue、watch两个方法,同时补充表单初始值配置:
const { register, handleSubmit, formState: { errors }, getValues, setValue, watch, } = useForm({ mode: "onChange", resolver: yupResolver(validationSchema), defaultValues: { termsOfUse: false, privacyPolicy: false } });
2. 绑定IonCheckbox事件
IonCheckbox的ionChange事件会在event.detail中返回当前勾选的布尔值,需将该值手动同步到RHF中,替换原来直接Spread register返回值的写法:
<div> <IonCheckbox checked={watch("termsOfUse")} onIonChange={(e) => setValue("termsOfUse", e.detail.checked, { shouldValidate: true })} /> <a href="xxx">I accept terms of use</a> </div> {errors.termsOfUse && <p>{errors.termsOfUse.message}</p>} <div> <IonCheckbox checked={watch("privacyPolicy")} onIonChange={(e) => setValue("privacyPolicy", e.detail.checked, { shouldValidate: true })} /> <a href="xxx">I accept privacy policy</a> </div> {errors.privacyPolicy && <p>{errors.privacyPolicy.message}</p>}
shouldValidate: true配置可在值更新后立刻触发Yup校验,匹配onChange校验模式。- 所有勾选状态完全由RHF统一维护,无独立本地状态导致的不同步问题。
3. 优化提交逻辑
handleSubmit会自动将所有表单值作为参数传入提交回调,无需手动通过getValues逐字段取值,提交逻辑可调整为:
const doCreateAccount = (formData) => { const data = { eMail: formData.email, password: formData.password, termsOfUse: formData.termsOfUse, privacyPolicy: formData.privacyPolicy }; axios .post("xx/register", data) .then((response) => response.data); };
校验规则适配说明
当前Yup中对两个复选框的规则定义:
termsOfUse: yup.boolean().oneOf([true], "You should accept terms of use"), privacyPolicy: yup.boolean().oneOf([true], "You should accept privacy policy"),
完全符合必填校验要求:由于初始值为布尔类型false,只有用户勾选后值变为true才会通过校验,无需额外追加.required()方法。当前使用的RHF、Yup、resolver版本均兼容该实现,无需升级依赖。
内容的提问来源于stack exchange,提问作者Ani
相关产品推荐
相关产品推荐

