在 React Hook Form 中,直接在 useForm 的 defaultValues 参数中使用静态默认值是首选方式,因为:
defaultValues是专门设计用于设置表单初始值的,它在钩子初始化时被缓存(cached),性能更好。- 它能正确支持
isDirty、dirtyFields等表单状态的计算(以defaultValues作为"单一真相来源")。 - 官方文档推荐:优先使用
defaultValues来管理整个表单的默认值,而不是单个输入的defaultValue。
示例:
tsx
const { register, handleSubmit } = useForm({
defaultValues: {
name: '初始姓名',
email: 'initial@example.com'
}
});
但是,如果默认值是异步获取的 (如从 API 加载数据),则推荐在 useEffect 中使用 reset(defaultValues):
原因:
defaultValues只在useForm初始渲染时读取一次(被缓存),后续 props 或 state 变化不会自动更新表单值。- 如果直接把异步数据传给
defaultValues,表单会先渲染为空(或初始空值),然后需要手动重置,导致可能出现"闪烁"(flash)或额外渲染。 - 使用
reset可以动态更新表单值,并正确重置表单状态(如清除 errors、touched 等)。
示例(异步加载场景):
tsx
const [asyncData, setAsyncData] = useState(null);
useEffect(() => {
fetch('/api/user').then(res => res.json()).then(data => {
setAsyncData(data);
});
}, []);
const { register, reset } = useForm({
defaultValues: { name: '', email: '' } // 先给空默认值,避免 uncontrolled 警告
});
useEffect(() => {
if (asyncData) {
reset(asyncData); // 这里更新表单值
}
}, [asyncData, reset]);
更现代的推荐(v7+):使用 values prop(而非 defaultValues)
从 React Hook Form v7 开始,引入了 values prop,它是响应式的 (reactive),会自动在值变化时调用内部 reset,无需手动 useEffect + reset。
- 适合异步数据加载,避免闪烁和额外渲染。
defaultValues仍用于静态初始值,values用于动态/异步更新。
示例:
tsx
const asyncValues = useFetch('/api/user'); // 假设返回 { name: '...', email: '...' }
const { register } = useForm({
defaultValues: { name: '', email: '' }, // 可选静态初始
values: asyncValues // 会自动响应变化更新表单
});
总结推荐
| 场景 | 推荐方式 | 原因 |
|---|---|---|
| 静态默认值(已知常量) | useForm({ defaultValues: {...} }) |
简单、性能好、官方首选 |
| 异步默认值(API 等) | values prop(首选) 或 useEffect + reset |
values 更优雅、无闪烁;reset 是传统可靠方式 |
| 需要手动重置表单 | reset(newValues) |
可保留/清除特定状态(如 keepDirtyValues) |
如果你的默认值是静态的,直接用 defaultValues 最好;如果是动态/异步的,优先试 values,否则用 reset。更多详情可参考官方文档:react-hook-form.com/docs/usefor...