复杂表单处理流程Hook

梦里水乡 +0/-0 0 0 正常 2025-12-24T07:01:19 React Hooks · 性能优化 · 表单处理

在复杂业务场景中,表单处理往往涉及多个字段验证、条件渲染、数据同步等复杂逻辑。本文分享一个实际的Hook重构方案,帮助解决这类问题。

问题场景:某电商订单表单包含商品信息、收货地址、支付方式等多个模块,其中地址信息根据用户选择的国家动态显示不同字段,同时需要实时验证每个字段的有效性。

原始实现问题

function OrderForm() {
  const [formData, setFormData] = useState({});
  const [errors, setErrors] = useState({});
  const [loading, setLoading] = useState(false);
  
  // 多个useEffect处理不同逻辑
  useEffect(() => {
    // 地址字段动态渲染逻辑
  }, [formData.country]);
  
  useEffect(() => {
    // 表单验证逻辑
  }, [formData]);
  
  useEffect(() => {
    // 数据同步逻辑
  }, [formData]);
}

重构方案:创建一个useComplexForm Hook

function useComplexForm(initialData, validators) {
  const [formData, setFormData] = useState(initialData);
  const [errors, setErrors] = useState({});
  const [touched, setTouched] = useState({});
  
  // 核心验证逻辑
  const validateField = (field, value) => {
    const validator = validators[field];
    if (!validator) return '';
    return validator(value);
  };
  
  // 字段更新处理
  const updateField = useCallback((field, value) => {
    setFormData(prev => ({ ...prev, [field]: value }));
    
    // 触发验证
    if (touched[field]) {
      const error = validateField(field, value);
      setErrors(prev => ({ ...prev, [field]: error }));
    }
  }, [touched, validators]);
  
  // 字段聚焦处理
  const handleFocus = useCallback((field) => {
    setTouched(prev => ({ ...prev, [field]: true }));
  }, []);
  
  return {
    formData,
    errors,
    touched,
    updateField,
    handleFocus,
    isValid: Object.values(errors).every(error => !error)
  };
}

使用示例

function OrderForm() {
  const validators = {
    email: value => !value.includes('@') ? '邮箱格式错误' : '',
    phone: value => !/^1[3-9]\d{9}$/.test(value) ? '手机号格式错误' : ''
  };
  
  const form = useComplexForm({
    country: 'CN',
    email: '',
    phone: ''
  }, validators);
  
  return (
    <form>
      <input 
        value={form.formData.email}
        onChange={(e) => form.updateField('email', e.target.value)}
        onFocus={() => form.handleFocus('email')}
      />
      {form.errors.email && <span>{form.errors.email}</span>}
    </form>
  );
}

通过该Hook重构,实现了表单逻辑的集中管理,避免了多个useEffect的复杂依赖关系,提升了代码可维护性和性能。

推广
广告位招租

讨论

0/2000