react-hook-form中MUI Button Group选中值无法更新,该如何解决?
问题原因及解决方案
问题根源
- 未同步Controller内部状态:直接调用
setValue而未使用Controller提供的field.onChange,导致Controller无法感知状态变化,表单全局状态未被正确更新。 - 缺少初始默认值:
useForm初始化时未设置defaultValues,表单初始状态为undefined,易引发同步异常。 getValues的异步特性:setValue是异步操作,同步调用getValues无法立即获取更新后的状态。
修复后的代码示例
import { ButtonGroup, Button } from '@mui/material' import { useForm, Controller } from 'react-hook-form' export default function MyComponent() { // 初始化表单默认值,确保状态有初始值 const { control, watch, getValues } = useForm({ defaultValues: { selectedOption: 'Option1' } }) // 用watch实时监听选中值变化,替代同步调用getValues const selectedOption = watch('selectedOption') const options = ['Option1', 'Option2', 'Option3'] return ( <> <Controller name="selectedOption" control={control} render={({ field }) => ( <ButtonGroup> {options.map((option) => ( <Button key={option} variant={field.value === option ? 'contained' : 'outlined'} // 使用field.onChange同步Controller与表单状态,这是规范集成方式 onClick={() => field.onChange(option)} > {option} </Button> ))} </ButtonGroup> )} /> {/* 实时展示选中值 */} <p>当前选中:{selectedOption}</p> {/* 异步获取最新值的示例 */} <Button onClick={() => { setTimeout(() => { console.log('最新选中值:', getValues('selectedOption')) }, 0) }}>获取最新值</Button> </> ) }
关键修复点说明
- 使用
field.onChange:Controller的field对象自带onChange方法,是react-hook-form集成自定义组件的标准方式,能确保组件状态与表单全局状态完全同步。 - 设置
defaultValues:初始化时指定默认值,避免因状态为undefined导致的渲染或同步问题。 - 正确获取更新后的值:
- 用
watch可以实时监听字段变化,直接拿到最新状态; - 若必须使用
getValues,需在异步回调(如setTimeout)中调用,或通过useEffect监听watch结果来触发后续操作,适配setValue的异步特性。
- 用
内容的提问来源于stack exchange,提问作者Mir Stephen
相关产品推荐
相关产品推荐

