useWatch设置的defaultValue未被实际字段值覆盖是什么原因?
useWatch监听自定义注册字段未同步更新问题原因及修复方案
问题根因
register方法第二个参数中传入的value仅会在字段首次注册时生效,后续组件重渲染时传入的新值不会主动触发表单字段的更新。你的写法仅在首次注册时给undefinedFields赋了初始值,后续field1、field2变化时,表单内该字段的实际值并没有同步更新。useWatch的defaultValue仅当目标字段在表单中无对应有效值时才会作为 fallback 返回。你监听的undefinedFields没有主动更新逻辑,表单内该字段一直未存储正确的最新值,因此useWatch会一直返回你设置的默认值true。- 额外补充:你当前判断「至少有一个字段为undefined」的逻辑存在问题,
field1 || field2会把0、false、空字符串等falsy值也判定为真,不符合你的业务需求,需要改为field1 === undefined || field2 === undefined。
修复方案
方案1(更推荐):直接计算派生值,无需额外注册表单字段
undefinedFields本身就是field1和field2的派生值,不需要额外存入表单,直接在需要用到该值的地方监听两个原始字段计算即可:
const [field1, field2] = useWatch({ control, name: ['field1Name', 'field2Name'], defaultValue: [field1DefaultValue, field2DefaultValue] }); const areThereUndefinedFields = field1 === undefined || field2 === undefined;
方案2:确实需要存储为表单字段时,用setValue主动同步更新
如果业务场景要求必须把该值注册为表单字段,需要配合useEffect监听字段变化,调用setValue主动更新表单内的undefinedFields值:
const field1 = useWatch({ control, name: 'field1Name', defaultValue: field1DefaultValue }); const field2 = useWatch({ control, name: 'field2Name', defaultValue: field2DefaultValue }); // 首次注册字段 useEffect(() => { register('undefinedFields', { value: field1 === undefined || field2 === undefined }); }, [register]); // 监听原始字段变化,主动更新派生字段值 useEffect(() => { setValue('undefinedFields', field1 === undefined || field2 === undefined); }, [field1, field2, setValue]);
另一端监听逻辑不需要修改,即可正常拿到最新值。
内容的提问来源于stack exchange,提问作者Lindsey
相关产品推荐
相关产品推荐

