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

React Native中react-hook-form Controller规则验证失效求助

解决React Hook Form中Controller与自定义验证规则配合的问题

核心问题分析

  1. 直接调用emailValidation()时未传入输入值,且react-hook-form要求验证函数需接收当前字段值作为参数。
  2. 验证函数内部使用useTranslation违反React Hook规则——Hook只能在组件或自定义Hook的顶层调用,不能在普通函数中使用。
  3. 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 16:37:52