如何在 React 中实现一个可复用的自定义 Hook 来管理表单状态和验证?
如何在 React 中实现一个可复用的自定义 Hook 来管理表单状态和验证?
回答与解析:
可以通过创建一个名为 useFormControl 的自定义 Hook 来集中处理表单字段的状态、输入变更、以及基本验证逻辑。以下是一个典型实现:
import { useState, useCallback } from 'react';
function useFormControl(initialValues, validationRules) {
const [values, setValues] = useState(initialValues);
const [errors, setErrors] = useState({});
const handleChange = useCallback((name, value) => {
setValues(prev => ({ ...prev, [name]: value }));
// 清除对应字段的错误(可选)
if (errors[name]) {
setErrors(prev => ({ ...prev, [name]: '' }));
}
}, [errors]);
const validate = useCallback(() => {
const newErrors = {};
for (const field in validationRules) {
const rule = validationRules[field];
if (rule.required && !values[field]) {
newErrors[field] = `${field} is required`;
} else if (rule.pattern && !rule.pattern.test(values[field])) {
newErrors[field] = rule.message || `Invalid ${field}`;
}
}
setErrors(newErrors);
return Object.keys(newErrors).length === 0;
}, [values, validationRules]);
const reset = useCallback(() => {
setValues(initialValues);
setErrors({});
}, [initialValues]);
return { values, errors, handleChange, validate, reset };
}
使用示例:
function LoginForm() {
const { values, errors, handleChange, validate } = useFormControl(
{ email: '', password: '' },
{
email: { required: true, pattern: /^[^\s@]+@[^\s@]+\.[^\s@]+$/, message: '请输入有效邮箱' },
password: { required: true }
}
);
const handleSubmit = (e) => {
e.preventDefault();
if (validate()) {
console.log('提交数据:', values);
}
};
return (
<form onSubmit={handleSubmit}>
<input
value={values.email}
onChange={(e) => handleChange('email', e.target.value)}
placeholder="邮箱"
/>
{errors.email && <span style={{ color: 'red' }}>{errors.email}</span>}
<input
type="password"
value={values.password}
onChange={(e) => handleChange('password', e.target.value)}
placeholder="密码"
/>
{errors.password && <span style={{ color: 'red' }}>{errors.password}</span>}
<button type="submit">登录</button>
</form>
);
}
解析:
- 自定义 Hook 将表单状态(values)、错误信息(errors)、变更处理(handleChange)、验证(validate)和重置(reset)封装在一起,提升复用性。
- 使用 useCallback 优化性能,避免每次渲染都生成新函数。
- 验证规则通过对象传入,支持 required 和正则 pattern 等常见规则,易于扩展。
- 该模式适用于中小型表单,复杂场景可考虑 Formik 或 React Hook Form 等成熟库。

发表评论 (审核通过后显示评论):