React-Hook-Form更新默认值后useFieldArray无法渲染动态字段
React-Hook-Form v6.14.1动态字段更新异常问题
使用React-Hook-Form v6.14.1开发动态表单,表单根据组件状态填充数据。初始加载一切正常,但更新状态后,除动态字段外其他数据均能正常显示。
预期行为
- 初始加载时,WAN 1标签页显示动态字段(WAN 1 VLAN-1),WAN2无动态字段
- 点击
Update Config按钮后,WAN1无动态字段,WAN2显示一个动态字段(WAN 2 VLAN-1)
实际行为
点击按钮后WAN2的动态字段未显示,useFieldArray返回的fields始终为空数组。
已尝试操作
- 按照官方文档使用
reset方法重置表单默认值 - 为动态字段设置
defaultValue - 搜索类似问题,但大多聚焦于已填充字段的值而非字段本身的显示
关键代码片段
App.js(状态管理与表单入口)
const [configdata, setConfigdata] = useState(config); return ( <div className="App"> <UpdateConfig onClick={() => setConfigdata(configUpdated)} /> <Form formData={configdata} handleFormData={(data) => console.log(data)} /> </div> );
Form.js(表单容器与Hook初始化)
使用FormProvider传递表单方法,动态渲染WanFields组件,并在formData更新时调用reset:
const methods = useForm({ defaultValues: props.formData }); useEffect(() => { methods.reset(props.formData); }, [props.formData]); return ( <FormProvider {...methods}> <form onSubmit={methods.handleSubmit((data) => props.handleFormData(data) )} > <Tab.Content> {props.formData?.intfs?.length && props.formData?.intfs.map((intf, index) => ( <Tab.Pane key={index} eventKey={`wan${index}-tab`}> <WanFields key={`wan${index}-fields`} intfNo={index} portTypeOptions={props.portTypeOptions} data={intf} /> </Tab.Pane> ))} </Tab.Content> </form> </FormProvider> );
WanFields.js(动态字段逻辑)
使用useFieldArray管理动态字段,根据watch值控制字段显示:
const methods = useFormContext(); const { errors, control, watch, register } = methods; const { fields, append, remove } = useFieldArray({ control, keyName: "fieldid", name: `intfs[${intfNo}].subIntfs` }); const watchIntfStatus = watch(`intfs[${intfNo}].enabledStatus`); const watchIntfType = watch(`intfs[${intfNo}].enabled`); // 动态字段渲染逻辑 {watchIntfType?.value >= "2" && ( <> <div className="form-group"> <div className="btn btn-success" onClick={append}> Add </div> </div> <div id={`accordion-${intfNo}`}> <Accordion> {console.log("FIELDS", fields)} {/* 问题:更新数据后fields为空数组 */} {fields.map((field, index) => ( <Card key={field.fieldid}> <Accordion.Toggle as={Card.Header} variant="link" eventKey={`${index}`} style={{ cursor: "pointer" }} > <h4> WAN {parseInt(intfNo) + 1}{" "} <span style={{ margin: "0px 5px" }}> <i className="fas fa-angle-right"></i> </span>{" "} VLAN-{index + 1} </h4> <div className="card-header-action"> <button type="button" className="btn btn-danger" onClick={() => remove(index)} > Remove </button> </div> </Accordion.Toggle> <Accordion.Collapse eventKey={`${index}`}> <Card.Body> <div className="form-row"> <div className="form-group col-12 col-md-6"> <label>IP</label> <input type="text" className="form-control" name={`intfs[${intfNo}].subIntfs[${index}].ipAddress`} defaultValue={field?.ipAddress} ref={register()} /> </div> <div className="form-group col-12 col-md-6"> <label>Subnet</label> <input type="number" className="form-control" min="0" max="30" name={`intfs[${intfNo}].subIntfs[${index}].subnet`} defaultValue={field?.subnet} ref={register()} /> </div> </div> </Card.Body> </Accordion.Collapse> </Card> ))} </Accordion> </div> </> )}
核心问题:更新状态后,表单默认值已更新,但useFieldArray的fields属性未同步更新,始终为空数组,导致动态字段无法渲染。
内容的提问来源于stack exchange,提问作者George
相关产品推荐
相关产品推荐

