React中react-hook-form的useFormContext下setValue对Select组件失效
问题修复方案
问题根源
- 父组件未从
methods中解构setValue,导致页面加载时的setValue调用无效。 - Material-UI的
Select属于自定义受控组件,直接使用register无法和React Hook Form正确同步值。 RHFSelect组件未声明multiple参数,且单选模式下默认值设为数组[],与组件模式不匹配。
修复步骤
1. 修正父组件逻辑
首先确保从methods中解构setValue,并添加正确的依赖项:
const ParentComponent= () =>{ const sizes = [{label:'Small', value:'small'}, {label:'Medium', value:'Medium'}] const methods = useForm(); // 解构出setValue,确保能正常调用 const { register, handleSubmit, setValue } = methods; useEffect(() => { setValue("purchasedPrice", 100) setValue("size", "Medium") }, [setValue]) // 添加setValue到依赖数组 return ( <FormProvider {...methods}> <RHFTextField name="purchasedPrice" /> {/* 单选模式下无需传数组默认值 */} <RHFSelect options={sizes} name="size" /> </FormProvider> ) }
2. 重构RHFSelect组件(推荐方案)
使用React Hook Form的Controller组件包裹Material-UI Select,这是处理自定义受控组件的标准方式:
import { Controller } from "react-hook-form"; const RHFSelect = ({name, options, multiple = false, defaultValue}) =>{ const { control, formState: { errors } } = useFormContext(); return ( <Controller name={name} control={control} // 根据多选/单选模式设置对应类型的默认值 defaultValue={multiple ? (defaultValue ?? []) : (defaultValue ?? '')} render={({ field }) => ( <Select multiple={multiple} {...field} > {options?.map((ele, index) => ( <MenuItem key={index} value={ele.value}>{ele.label}</MenuItem> ))} </Select> )} /> ) }
3. 备选方案(直接使用register)
如果坚持用register,需要手动适配Select的事件回调:
const RHFSelect = ({name, options, multiple = false, defaultValue}) =>{ const {register, formState: { errors }} = useFormContext(); const { ref, onChange, ...rest } = register(name); const handleSelectChange = (e) => { // 适配Select的选中值格式传给React Hook Form onChange(multiple ? e.target.value : e.target.value); } return ( <Select multiple={multiple} ref={ref} onChange={handleSelectChange} {...rest} defaultValue={multiple ? (defaultValue ?? []) : (defaultValue ?? '')} > {options?.map((ele, index) => ( <MenuItem key={index} value={ele.value}>{ele.label}</MenuItem> ))} </Select> ) }
核心注意点
- 单选模式下默认值应为单个值,多选模式才用数组,避免类型不匹配。
Controller能自动处理自定义组件的状态同步,是React Hook Form官方推荐的自定义组件集成方式。
内容的提问来源于stack exchange,提问作者ASIF KAIF
相关产品推荐
相关产品推荐

