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

如何将react-hooks-form与@Mui的Select组件关联并设置默认值

解决MUI Select与react-hook-form的关联及默认值设置问题

你的核心问题是手动维护了gender状态并设置了value和onChange,这和react-hook-form的register表单状态管理逻辑冲突,导致Select组件失效。以下是两种完全基于react-hook-form、无需额外useState的解决方案:

方法一:使用register配合setValue设置默认值

直接通过register接管Select的状态管理,异步获取的默认值用react-hook-form的setValue方法设置:

import axios from 'axios';
import React, { useEffect } from 'react';
import { useForm } from 'react-hook-form';
import { FormControl, InputLabel, Select, MenuItem } from '@mui/material';

export default function FormSelect() {
  const {
    register,
    setValue,
    formState: { errors },
  } = useForm({});
  
  useEffect(() => {
    axios.get('/get-gender').then((data) => {
      // 确保后端返回的gender值与MenuItem的value类型一致(此处为数字)
      setValue('gender', data.data.gender);
    });
  }, [setValue]);

  return (
    <FormControl fullWidth error={!!errors.gender}>
      <InputLabel id="gender">Gender</InputLabel>
      <Select
        labelId="gender"
        id="gender-select"
        label="Gender"
        {...register("gender", {
          required: "Gender is required"
        })}
      >
        <MenuItem value={1}>Male</MenuItem>
        <MenuItem value={2}>Female</MenuItem>
      </Select>
      {errors.gender && <span>{errors.gender.message}</span>}
    </FormControl>
  );
}

方法二:使用Controller组件(适配MUI受控组件)

如果直接用register遇到兼容性问题,react-hook-form提供的Controller组件专门用于整合第三方受控组件,逻辑更清晰:

import axios from 'axios';
import React, { useEffect } from 'react';
import { useForm, Controller } from 'react-hook-form';
import { FormControl, InputLabel, Select, MenuItem } from '@mui/material';

export default function FormSelect() {
  const {
    control,
    setValue,
    formState: { errors },
  } = useForm({});
  
  useEffect(() => {
    axios.get('/get-gender').then((data) => {
      setValue('gender', data.data.gender);
    });
  }, [setValue]);

  return (
    <FormControl fullWidth error={!!errors.gender}>
      <InputLabel id="gender">Gender</InputLabel>
      <Controller
        name="gender"
        control={control}
        rules={{ required: "Gender is required" }}
        render={({ field }) => (
          <Select
            labelId="gender"
            id="gender-select"
            label="Gender"
            value={field.value || ''}
            onChange={field.onChange}
          >
            <MenuItem value={1}>Male</MenuItem>
            <MenuItem value={2}>Female</MenuItem>
          </Select>
        )}
      />
      {errors.gender && <span>{errors.gender.message}</span>}
    </FormControl>
  );
}

关键注意点

  • 两种方案都无需手动维护useState,完全交由react-hook-form管理表单状态
  • 异步获取的默认值通过setValue方法设置,确保组件挂载后正确更新表单
  • 必须保证后端返回的gender值与MenuItem的value类型一致(比如都是数字或字符串),否则会出现匹配失败的情况
  • 验证规则统一在register或Controller的rules中定义,提交时react-hook-form会自动校验所有字段

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 01:05:36