如何通过React Hook Form Controller与Hero UI动态设置Autocomplete默认值
问题分析
你当前的核心问题是:React Hook Form 的 defaultValues 仅在表单初始化阶段生效,后续通过 setEndDefaultValue 更新外部状态无法同步到表单的 end 字段值,导致结束时间的Autocomplete组件无法动态更新默认选中项。
解决方案
- 移除
defaultValues中针对end的useMemo逻辑,因为它无法实现动态更新表单值的需求 - 在监听开始时间变化的
useEffect中,更新结束时间选项后,直接调用 React Hook Form 的setValue方法修改end字段的表单值 - 确保Autocomplete组件的
defaultSelectedKey绑定表单字段的value,实现表单值与组件选中状态的自动同步
修改后的代码
状态与表单初始化
const [endDefaultValue, setEndDefaultValue] = useState<string>("08:0") const watchStart = watch("start") const { trigger, setValue, control, handleSubmit, register, reset, watch, formState: { errors, isSubmitSuccessful }, } = useForm<TAddAppointmentFormInput>({ resolver: zodResolver(appointmentSchema), defaultValues: { start: `${props.start.getHours().toString().padStart(2, "0")}:0`, end: "08:0" // 仅设置初始化默认值,后续动态更新依赖setValue } });
监听开始时间变化的Effect
useEffect(() => { setStartOptions(startoptions) setEndOptions(endoptions) // 直接更新表单的end字段值,同步到Autocomplete组件 const newEndDefault = endoptions[0].hour; setEndDefaultValue(newEndDefault); setValue("end", newEndDefault); }, [watchStart, setValue]); // 需将setValue加入依赖数组,避免闭包问题
结束时间Autocomplete组件(保持原有逻辑即可)
<Controller control={control} name="end" render={({ field: { onChange, onBlur, value, ref } }) => ( <Autocomplete defaultItems={endOptions} size="md" defaultSelectedKey={value} // 绑定表单字段值,自动同步选中状态 onSelectionChange={onChange} radius="sm" onBlur={onBlur} isClearable={false} isInvalid={errors.endDate ? true : false} errorMessage={errors.endDate?.message} isDisabled={ selected === "Lezione Privata" || selected === "Lezione a Duetto" } > {(slot) => ( <AutocompleteItem key={slot.hour}> {slot.hour} </AutocompleteItem> )} </Autocomplete> )} />
关键说明
- React Hook Form 的表单状态由其内部管理,外部 state 的更新不会自动同步到表单字段,必须通过
setValue方法主动触发更新 defaultValues仅在组件挂载或调用reset时生效,动态更新表单值必须使用setValue- 确保
useEffect的依赖数组包含setValue,避免因闭包导致的旧方法引用问题
内容的提问来源于stack exchange,提问作者Luca Ponzanelli
相关产品推荐
相关产品推荐

