You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MUI Select结合react-hook-form设置defaultValue后无法修改值

问题根因

问题出在值类型不匹配:

  • 你给Controller配置的defaultValue是空字符串"",属于基础类型
  • 但Select的MenuItem绑定的value是整个对象类型
    MUI Select内部通过严格相等(===)判断选中项,空字符串和任何对象都不可能相等,所以选中状态无法正常渲染更新。另外你的代码还有两个隐藏问题:一是错误状态读取用错了字段名,二是自定义了完全没被调用的handleChange逻辑,属于冗余代码。
修复步骤
  • 修正Controller的默认值类型:初始无选中项时不要用空字符串作为默认值,改用null,和后续选中的对象类型保持兼容。
  • 给Select的值加空态兜底:未选中时把value fallback为空字符串,适配MUI InputLabel的浮动逻辑,避免label和选中值重叠。
  • 修正错误状态读取逻辑:Controller绑定的表单字段名是formname,读取errors时也要用这个字段名,之前用name会导致校验错误无法正常显示。
  • (推荐)统一配置表单默认值:不要在单个Controller上配置defaultValue,把所有字段的初始值统一放到useForm初始化的defaultValues参数里,这样调用reset方法时能正常重置,也不会出现字段值联动异常。
修复后核心代码
function MySelect({ formname, name, setSelected, data = [] }) {
  const {
    control,
    formState: { errors },
    watch
  } = useFormContext();

  // 如果需要同步选中值到外部,直接用watch监听对应字段即可
  const selectedValue = watch(formname);
  React.useEffect(() => {
    if (setSelected) setSelected(selectedValue);
  }, [selectedValue, setSelected]);

  return (
    <Box sx={{minWidth: 120}}>
      <InputLabel id="demo-multiple-name-label">{name}</InputLabel>
      <Controller
        name={formname}
        control={control}
        // 如果已经在useForm里配置了defaultValues,这里可以删掉defaultValue配置
        defaultValue={null}
        render={({ field: { onChange, value } }) => (
          <Select
            sx={{ width: 200 }}
            labelId="demo-multiple-name-label"
            id="demo-multiple-name"
            multiple={false}
            value={value ?? ''}
            onChange={onChange}
            input={<OutlinedInput label={name} />}
            MenuProps={MenuProps}
            error={!!errors[formname]}
            helperText={errors[formname]?.message || ''}
          >
            {data.map((element, i) => {
              if (element.bsa_maskenkey)
                return (
                  <MenuItem value={element} key={i}>
                    {`${element.bsa_maskenkey} ${element.we_menge}`}
                  </MenuItem>
                );
              else if (element.blager_maskenkey)
                return (
                  <MenuItem value={element} key={i}>
                    {`${element.blager_maskenkey} ${element.blagerpo_maskenkey} | Menge: ${element.summe}`}
                  </MenuItem>
                );
              else
                return (
                  <MenuItem value={element} key={i}>
                    {`${element.objekt} | Menge: ${element.menge}`}
                  </MenuItem>
                );
            })}
          </Select>
        )}
      />
    </Box>
  );
}

外层useForm配置参考:

const methods = useForm({
  defaultValues: {
    // 对应传入MySelect的formname字段,初始值设为null
    // 其他表单字段也在这里统一配置初始值
  }
});

内容的提问来源于stack exchange,提问作者Nicklas Desens

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 03:00:58