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

Material UI Select在React Hook Form中初始默认值不显示问题

问题解决思路及方案

核心问题分析

初始页面刷新时,Redux中的defaultTemplates可能还未加载完成,导致defaultTemplate为undefined;而React Hook Form的defaultValues仅在组件初始化时生效一次,后续Redux数据更新后不会自动同步到表单默认值。即使后续defaultTemplate获取到有效值,表单也不会重新初始化,因此初始渲染时Select组件无法显示默认值;而切换页面返回时,Redux数据已加载完成,表单重新初始化后才能正常显示默认值。

具体修复步骤

1. 监听数据加载完成后同步表单默认值

使用useEffect监听defaultTemplates的变化,当数据就绪后调用reset方法更新表单值,确保表单能获取到正确的默认值:

const { control, reset } = useForm<IFormInput>({
  defaultValues: {
    templateType: undefined // 初始设为undefined,避免无效值
  }
});

useEffect(() => {
  if (defaultTemplates?.length) {
    const assignedTemplate = createTenant?.quota?.selected_template || 'Small';
    const defaultTemplate = defaultTemplates.find(template => template.template_name === assignedTemplate);
    reset({ templateType: defaultTemplate });
  }
}, [defaultTemplates, createTenant, reset]);

2. 优化Select组件的value处理逻辑

给Controller显式设置defaultValue,同时完善renderValue的空值处理,避免渲染异常:

<Controller
  name={name}
  control={control}
  defaultValue={undefined}
  render={({ field }) => (
    <Select
      fullWidth
      {...field}
      onChange={(e) => field.onChange(e.target.value)}
      renderValue={(selected) => {
        if (!selected) return ''; // 处理selected为undefined的情况
        return dropDownOptionKey ? selected[dropDownOptionKey] : selected;
      }}
    >
      {generateSingleOptions()}
    </Select>
  )}
/>

3. 修复MenuItem的key值问题

避免使用index作为MenuItem的key,改用数据中的唯一标识(如template_name),确保组件渲染的稳定性:

const generateSingleOptions = () => {
  return dropDownOptions?.map((option: any) => (
    <MenuItem key={option.template_name} value={option}>
      {dropDownOptionKey ? option[dropDownOptionKey] : option}
    </MenuItem>
  ));
};

完整修复后的代码片段

FormInputDropDown组件

const FormInputDropDown: React.FC<FormInputProps> = ({
  name,
  control,
  handleDropDownChange,
  dropDownOptionKey,
  dropDownOptions
}) => {
  const generateSingleOptions = () => {
    return dropDownOptions?.map((option: any) => (
      <MenuItem key={option.template_name} value={option}>
        {dropDownOptionKey ? option[dropDownOptionKey] : option}
      </MenuItem>
    ));
  };

  return (
    <Controller
      name={name}
      control={control}
      defaultValue={undefined}
      render={({ field }) => (
        <Select
          fullWidth
          {...field}
          onChange={(e) => field.onChange(e.target.value)}
          renderValue={(selected) => {
            if (!selected) return '';
            return dropDownOptionKey ? selected[dropDownOptionKey] : selected;
          }}
        >
          {generateSingleOptions()}
        </Select>
      )}
    />
  );
};

export default FormInputDropDown;

表单使用部分

interface IFormInput {
  templateType: TenantTemplate | undefined;
}

const createTenant = useSelector((state: RootState) => state.createTenant);
const defaultTemplates = useSelector((state: RootState) => state.buTemplates.templates);

const { control, reset } = useForm<IFormInput>({
  defaultValues: {
    templateType: undefined
  }
});

useEffect(() => {
  if (defaultTemplates?.length) {
    const assignedTemplate = createTenant?.quota?.selected_template || 'Small';
    const defaultTemplate = defaultTemplates.find(template => template.template_name === assignedTemplate);
    reset({ templateType: defaultTemplate });
  }
}, [defaultTemplates, createTenant, reset]);

<FormInputDropDown
  name="templateType"
  control={control}
  dropDownOptions={defaultTemplates || []}
  dropDownOptionKey="template_name"
/>

内容的提问来源于stack exchange,提问作者Saksham Singh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 12:15:07