React Native中react-hook-form Controller规则验证失效求助
解决React Hook Form中Controller与自定义验证规则配合的问题
核心问题分析
- 直接调用
emailValidation()时未传入输入值,且react-hook-form要求验证函数需接收当前字段值作为参数。 - 验证函数内部使用
useTranslation违反React Hook规则——Hook只能在组件或自定义Hook的顶层调用,不能在普通函数中使用。 - minLength/maxLength的配置格式不符合react-hook-form要求,需指定规则值和错误信息。
解决方案及代码修改
方案1:将验证函数移至组件内部(推荐)
在组件内部定义验证函数,可直接使用useTranslation,同时让函数接收输入值作为参数:
const formKeys = { email: 'email', password: 'password', }; const LoginScreen = () => { const { t } = useTranslation(); const { handleSubmit, control, formState: { errors }, } = useForm(); // 组件内部定义验证函数,直接使用t const emailValidation = (value: string): boolean | string => { const emailRegx = /^[a-zA-Z0-9]+@[a-zA-Z0-9]+\.[A-Za-z]+$/; if (!value) { return `${t('common:email')} ${t('common:errorMessages:isRequired')}`; } return emailRegx.test(value) || t('common:errorMessages:invalidEmailAddress'); }; return ( <Controller control={control} name={formKeys.email} render={({ field: { onChange, value } }) => ( <InputFields errorMessage={errors[formKeys.email]?.message} value={value} onChangeText={onChange} autoCapitalize={'none'} placeholder={t('common:email')} image={ <View style={styles.userIconsStyle}> <EmailIcon /> </View> } /> )} rules={{ // 用validate字段绑定自定义验证函数 validate: emailValidation, // 正确配置minLength规则,含自定义错误信息 minLength: { value: validationSchema.email.minLength, message: t('common:errorMessages:minLength', { length: validationSchema.email.minLength }) }, // 正确配置maxLength规则 maxLength: { value: validationSchema.email.maxLength, message: t('common:errorMessages:maxLength', { length: validationSchema.email.maxLength }) } }} /> ); };
方案2:将翻译函数传入全局验证函数
如果要保留全局的验证函数,需将t作为参数传入,避免在函数内部使用Hook:
// 全局验证函数,接收t和输入值 export const emailValidation = (t: TranslateFunc, value: string): boolean | string => { const emailRegx = /^[a-zA-Z0-9]+@[a-zA-Z0-9]+\.[A-Za-z]+$/; if (!value) { return `${t('common:email')} ${t('common:errorMessages:isRequired')}`; } return emailRegx.test(value) || t('common:errorMessages:invalidEmailAddress'); }; // 组件中使用 const LoginScreen = () => { const { t } = useTranslation(); const { handleSubmit, control, formState: { errors } } = useForm(); return ( <Controller control={control} name={formKeys.email} render={({ field: { onChange, value } }) => ( <InputFields errorMessage={errors[formKeys.email]?.message} value={value} onChangeText={onChange} autoCapitalize={'none'} placeholder={t('common:email')} image={ <View style={styles.userIconsStyle}> <EmailIcon /> </View> } /> )} rules={{ validate: (value) => emailValidation(t, value), minLength: { value: validationSchema.email.minLength, message: t('common:errorMessages:minLength', { length: validationSchema.email.minLength }) }, maxLength: { value: validationSchema.email.maxLength, message: t('common:errorMessages:maxLength', { length: validationSchema.email.maxLength }) } }} /> ); };
关键说明
- react-hook-form的
rules.validate字段接收一个函数,参数为当前字段的值,返回true表示验证通过,返回字符串则为错误提示信息。 - 内置规则(如minLength/maxLength)需以对象形式配置,通过
value指定规则阈值,message自定义错误提示。 - React Hook只能在组件或自定义Hook的顶层调用,禁止在普通验证函数内部使用。
内容的提问来源于stack exchange,提问作者ttars
相关产品推荐
相关产品推荐

