React Hook Form多组件调用useFieldArray追加数组字段不更新问题
问题原因
这个现象是react-hook-form中useFieldArray的底层设计逻辑导致的:
- 每个独立调用的
useFieldArray实例会在组件内部维护一份fields状态的本地副本,为了避免全局广播更新带来的不必要重渲染,react-hook-form默认不会跨实例同步同名字段数组的状态变更。你在IncomeInfo中调用append时,只会修改表单核心store中的数据,所以getValues能拿到最新值,但IncomeBaseTable里ArrayField组件内部的useFieldArray实例的本地fields状态没有收到更新通知,因此不会重渲染。 - 你在
IncomeBaseTable内部调用追加操作时,修改动作和fields状态属于同一个useFieldArray实例,修改后实例自身的状态会同步更新,因此可以正常触发重渲染。
关于多实例限制的说明
这个设计是性能优化的trade-off,数组字段往往是表单中更新频率最高、数据量最大的部分,如果默认开启所有同名字段数组实例的同步更新,很容易导致大面积的无意义重渲染,拖慢表单的响应速度。
你采用的「父组件声明单实例透传」是非常合理的解决方式,也并没有违背Hook的设计初衷:Hook的核心目标是逻辑复用,而跨组件的状态共享本身就依赖props传递或者Context分发,透传useFieldArray实例的开销远低于跨实例同步的状态订阅开销,是更高效的实现方式。
如果不想透传实例,在v7.22.0以上版本的react-hook-form中,你可以给所有监听同名字段的useFieldArray实例配置相同的keyName参数,即可实现多实例状态自动同步:
const { append, fields } = useFieldArray({ control, name: "incomeBase", keyName: "unique_id", // 所有同字段的实例配置相同的keyName即可 });
内容的提问来源于stack exchange,提问作者Leff
相关产品推荐
相关产品推荐

