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

如何将React Hook Form与React MUI Select组件结合并解决异常?

React Hook Form 结合 MUI Select 组件的状态异常问题解决

问题场景

使用 React Hook Form 搭配 MUI Select 组件时,出现初始值不生效、控制台抛出值越界及受控/非受控切换的错误,代码及问题如下:

原代码

import { zodResolver } from '@hookform/resolvers/zod';
import {
  Button,
  FormControl,
  FormHelperText,
  InputLabel,
  MenuItem,
  Select,
} from '@mui/material';
import { type SubmitHandler, useForm } from 'react-hook-form';
import { z } from 'zod';

function App() {
  const formFieldsSchema = z.object({
    selected: z.enum(['foo', 'bar', 'baz']),
  });

  const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm<z.infer<typeof formFieldsSchema>>({
    resolver: zodResolver(formFieldsSchema),
    defaultValues: {
      selected: 'bar',
    },
  });

  const onSubmit: SubmitHandler<z.infer<typeof formFieldsSchema>> = (data) =>
    console.log(data);

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <FormControl fullWidth error={errors.selected !== undefined}>
        <InputLabel>Selected</InputLabel>
        <Select {...register('selected')}>
          {['foo', 'bar', 'baz'].map((option) => (
            <MenuItem key={option} value={option}>
              {option}
            </MenuItem>
          ))}
        </Select>
        <FormHelperText>{errors.selected?.message}</FormHelperText>
      </FormControl>
      <Button type="submit">Submit</Button>
    </form>
  );
}

预期与实际问题

  • 预期行为:Select 默认选中 bar,切换选项时正常更新表单状态
  • 实际错误:
    1. 初始渲染时抛出警告:

      MUI: You have provided an out-of-range value undefined for the select (name="selected") component. Consider providing a value that matches one of the available options or ''. The available values are foo, bar, baz.

    2. 切换选项时抛出错误:

      A component is changing an uncontrolled input to be controlled. This is likely caused by the value changing from undefined to a defined value, which should not happen. Decide between using a controlled or uncontrolled input element for the lifetime of the component.

解决方案

核心原因是 MUI Select 作为受控组件,与 React Hook Form 的 register 方法适配性不佳,需使用 RHF 提供的 Controller 组件来统一管理第三方受控组件的状态同步。

修改步骤

  1. 从 react-hook-form 导入 Controller 组件
  2. 用 Controller 包裹 MUI Select,通过 render 属性传递组件所需的 value 和 onChange,同时关联 InputLabel 的 ID 避免标签错位

修改后完整代码

import { zodResolver } from '@hookform/resolvers/zod';
import {
  Button,
  FormControl,
  FormHelperText,
  InputLabel,
  MenuItem,
  Select,
} from '@mui/material';
import { type SubmitHandler, useForm, Controller } from 'react-hook-form'; // 新增导入Controller
import { z } from 'zod';

function App() {
  const formFieldsSchema = z.object({
    selected: z.enum(['foo', 'bar', 'baz']),
  });

  const {
    control, // 新增control属性,用于Controller
    handleSubmit,
    formState: { errors },
  } = useForm<z.infer<typeof formFieldsSchema>>({
    resolver: zodResolver(formFieldsSchema),
    defaultValues: {
      selected: 'bar',
    },
  });

  const onSubmit: SubmitHandler<z.infer<typeof formFieldsSchema>> = (data) =>
    console.log(data);

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <FormControl fullWidth error={errors.selected !== undefined}>
        <InputLabel id="select-label">Selected</InputLabel> {/* 添加id */}
        <Controller
          name="selected"
          control={control}
          render={({ field }) => (
            <Select
              labelId="select-label" // 关联InputLabel的id
              label="Selected"
              {...field} // 传递value和onChange
            >
              {['foo', 'bar', 'baz'].map((option) => (
                <MenuItem key={option} value={option}>
                  {option}
                </MenuItem>
              ))}
            </Select>
          )}
        />
        <FormHelperText>{errors.selected?.message}</FormHelperText>
      </FormControl>
      <Button type="submit">Submit</Button>
    </form>
  );
}

原理说明

Controller 是 React Hook Form 专门为第三方受控组件设计的适配层,它会自动同步表单状态与组件的 value,同时处理 onChange 事件的格式转换,确保初始默认值能正确传递给 MUI Select,避免出现 undefined 导致的受控/非受控切换错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 15:42:12