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

React Hook Form实现表单校验通过前禁用按钮的方案

解决React Hook Form表单按钮动态禁用问题

你完全不需要手动用useState维护禁用状态,React Hook Form内置的formState对象已经提供了实时的表单校验状态,直接用它来控制按钮的禁用状态就行。

核心实现步骤

  • 从useForm中解构出formState,里面包含isValid(所有字段通过校验时为true)和errors(存储字段错误信息)。
  • 将BigButton的disabled属性设置为!formState.isValid,也可以结合isDirty确保用户至少修改过表单再启用按钮,避免初始空表单时按钮误启用。

完整代码示例

import React from 'react';
import { View, TextInput, Text } from 'react-native';
import { useForm, Controller } from 'react-hook-form';
import BigButton from './BigButton'; // 替换为你的BigButton组件路径

const RegisterForm = () => {
  const { control, handleSubmit, formState: { errors, isValid, isDirty } } = useForm({
    mode: 'onChange', // 输入变化时实时校验,保证状态实时更新
    defaultValues: {
      username: '',
      email: '',
      password: ''
    }
  });

  const onSubmit = (data) => {
    // 处理注册提交逻辑
    console.log('注册数据:', data);
  };

  return (
    <View style={{ padding: 20 }}>
      {/* 用户名输入框 */}
      <Controller
        control={control}
        name="username"
        rules={{
          required: '用户名不能为空',
          minLength: { value: 3, message: '用户名至少3个字符' }
        }}
        render={({ field: { onChange, onBlur, value } }) => (
          <View>
            <TextInput
              onBlur={onBlur}
              onChangeText={onChange}
              value={value}
              placeholder="请输入用户名"
              style={{ 
                borderWidth: 1, 
                borderColor: errors.username ? 'red' : '#ccc', 
                padding: 10, 
                marginBottom: 10 
              }}
            />
            {errors.username && <Text style={{ color: 'red', marginBottom: 10 }}>{errors.username.message}</Text>}
          </View>
        )}
      />

      {/* 邮箱输入框 */}
      <Controller
        control={control}
        name="email"
        rules={{
          required: '邮箱不能为空',
          pattern: { value: /^\S+@\S+$/i, message: '请输入有效的邮箱地址' }
        }}
        render={({ field: { onChange, onBlur, value } }) => (
          <View>
            <TextInput
              onBlur={onBlur}
              onChangeText={onChange}
              value={value}
              placeholder="请输入邮箱"
              keyboardType="email-address"
              style={{ 
                borderWidth: 1, 
                borderColor: errors.email ? 'red' : '#ccc', 
                padding: 10, 
                marginBottom: 10 
              }}
            />
            {errors.email && <Text style={{ color: 'red', marginBottom: 10 }}>{errors.email.message}</Text>}
          </View>
        )}
      />

      {/* 密码输入框 */}
      <Controller
        control={control}
        name="password"
        rules={{
          required: '密码不能为空',
          minLength: { value: 6, message: '密码至少6个字符' }
        }}
        render={({ field: { onChange, onBlur, value } }) => (
          <View>
            <TextInput
              onBlur={onBlur}
              onChangeText={onChange}
              value={value}
              placeholder="请输入密码"
              secureTextEntry
              style={{ 
                borderWidth: 1, 
                borderColor: errors.password ? 'red' : '#ccc', 
                padding: 10, 
                marginBottom: 20 
              }}
            />
            {errors.password && <Text style={{ color: 'red', marginBottom: 20 }}>{errors.password.message}</Text>}
          </View>
        )}
      />

      {/* 提交按钮 */}
      <BigButton
        title="注册"
        onPress={handleSubmit(onSubmit)}
        disabled={!isValid || !isDirty} // 所有字段校验通过且用户修改过表单才启用
        // 若不需要限制用户修改,直接用 disabled={!isValid} 即可
      />
    </View>
  );
};

export default RegisterForm;

关键说明

  • mode: 'onChange':设置输入变化时立即校验,确保isValid状态实时更新。如果用默认的onSubmit模式,只有点击提交时才会校验,按钮状态不会实时变化。
  • isValid:所有字段满足校验规则时为true,否则为false,是控制按钮禁用的核心依据。
  • isDirty:用户修改过至少一个字段时为true,避免初始空表单(若默认值恰好符合校验规则)时按钮直接启用的情况。
  • 无需手动维护disable状态:React Hook Form会自动跟踪表单状态,只要依赖formState里的属性,组件就会自动重渲染更新按钮状态。

内容的提问来源于stack exchange,提问作者yzned

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 05:15:16