react-hook-form中props传入的defaultValues未填充输入框如何解决
问题根因
react-hook-form的defaultValues仅在组件首次初始化时读取一次。你父组件传递的props.client是异步获取的,第一次组件渲染时props.client为空,表单已经用空值完成初始化;后续props.client拿到正确值时,useForm不会主动重新读取defaultValues,因此输入框不会自动填充。
解决方案1:监听props变化调用reset重置表单
在组件内添加useEffect,监听props.client的变化,当拿到有效值时调用reset方法更新表单全部值,代码修改如下:
import { useEffect } from 'react'; const ClientAddEdit = (props) => { const { control, register, handleSubmit, reset, formState: { errors } } = useForm({ defaultValues: props.client // 保留默认值配置,适配新增场景下props.client本身就是初始空对象的情况 }); // 新增useEffect监听client变化 useEffect(() => { // 确保client有有效值时才重置,避免覆盖用户已输入内容 if(props.client?.clientCode) { reset(props.client) } }, [props.client, reset]) const onSubmit = (data) => { // 原有提交逻辑 } return ( <div> <Form className="mt-2" onSubmit={handleSubmit(onSubmit)}> <Label for="clientCode">Client Code</Label> <Input type="text" name="clientCode" className={errors.clientCode && "is-invalid"} {...register("clientCode", { required: "Required", maxLength: { value: 10, message: "Max Length: 10" } })} /> {errors.clientCode ? ( <div className="invalid-tooltip mt-25">{errors.clientCode.message}</div> ) : null} <Label for="clientName">Client Name</Label> <Input type="text" name="clientName" className={errors.clientName && "is-invalid"} {...register("clientName", { required: "Required", maxLength: { value: 100, message: "Max Length: 100" } })} /> {errors.clientName ? ( <div className="invalid-tooltip mt-25">{errors.clientName.message}</div> ) : null} </Form> </div> ) }
如果之前尝试reset没有生效,大概率是没有把props.client加到useEffect的依赖数组里,或者调用reset的时候没有传入新的client对象作为参数。
解决方案2:父组件控制渲染时机/添加key重新初始化组件
如果不想在子组件加额外逻辑,可以在父组件调用ClientAddEdit的地方做处理:
- 父组件拿到client有效值之后再渲染
ClientAddEdit组件:
// 父组件内代码 { client && <ClientAddEdit client={client} /> }
- 或者给
ClientAddEdit添加唯一key,当client加载完成后key变化会触发组件重新初始化,自动读取最新的defaultValues:
// 父组件内代码,用client的唯一标识比如id作为key,新增场景可以用固定字符串比如'new' <ClientAddEdit key={client?.id || 'new'} client={client} />
内容的提问来源于stack exchange,提问作者tickwave
相关产品推荐
相关产品推荐

