在复杂业务场景中,表单处理往往涉及多个字段验证、条件渲染、数据同步等复杂逻辑。本文分享一个实际的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的复杂依赖关系,提升了代码可维护性和性能。

讨论