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

如何使用React Hook Form和Yup验证Material UI多选Autocomplete TextField?

你遇到的报错是两个原因共同导致的:

  1. 多选模式下的Material UI Autocomplete返回值为数组类型,因此用Yup.string()校验规则类型不匹配,即便选中选项也会触发报错。
  2. 你直接将react-hook-form的register绑定到了Autocomplete内部的TextField上,此时RHF收集到的是TextField输入框的搜索值,而不是Autocomplete的选中数组,初始状态下是空字符串,和你预期的数组类型不匹配,因此触发must be a array type的报错。

步骤1:修改Yup校验规则

改用数组类型的校验规则,根据你的选项结构配置校验逻辑,示例如下:

const validationSchema = Yup.object().shape({
  daysOfWeek: Yup.array()
    // 如果你的选项是对象结构,可补充内部字段校验
    .of(Yup.object({
      label: Yup.string().required(),
      value: Yup.string().required()
    }))
    .min(1, "至少选择一天")
    .required("Days of the week are required")
});

步骤2:使用Controller包裹Autocomplete

register仅适用于原生表单控件,对于MUI Autocomplete这类自定义受控组件,需要使用react-hook-form提供的Controller组件做状态桥接,不需要自己额外维护selected状态,RHF会托管表单状态。

完整修改后代码示例

import { Controller, useForm } from "react-hook-form";
import { yupResolver } from "@hookform/resolvers/yup";
import * as Yup from "yup";
import { Autocomplete, TextField, Typography } from "@mui/material";

const validationSchema = Yup.object().shape({
  daysOfWeek: Yup.array()
    .of(Yup.object({
      label: Yup.string().required(),
      value: Yup.string().required()
    }))
    .min(1, "至少选择一天")
    .required("Days of the week are required")
});

function YourFormComponent() {
  const {
    formState: {errors},
    handleSubmit,
    control // controller需要用到control实例
  } = useForm({
    resolver: yupResolver(validationSchema),
    defaultValues: {
      daysOfWeek: [] // 初始值设为空数组,避免类型报错
    }
  });

  const onSubmit = (data) => {
    // 此处拿到的data.daysOfWeek就是选中的选项数组
    console.log(data.daysOfWeek);
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <Controller
        name="daysOfWeek"
        control={control}
        render={({ field }) => (
          <Autocomplete
            disableClearable
            disablePortal
            filterSelectedOptions
            multiple
            getOptionDisabled={(option) => !!option.disabled}
            getOptionLabel={(option) => option.label}
            id="days-autocomplete"
            options={daysOfWeekSuggestions}
            // 直接用controller提供的onChange和value做状态绑定
            onChange={(_, value) => field.onChange(value)}
            value={field.value}
            renderInput={(params) => (
              <TextField
                required
                error={!!errors.daysOfWeek}
                id="daysOfWeek"
                label="Days of the week"
                name="daysOfWeek"
                type="search"
                {...params}
              />
            )}
          />
        )}
      />

      <Typography color="error" sx={errorSx} variant="inherit">
        {errors.daysOfWeek?.message}
      </Typography>
      
      <button type="submit">提交</button>
    </form>
  )
}

可选方案:保留自定义selected状态

如果你的业务逻辑需要单独维护选中状态,可以在Controller的onChange回调中同时更新自定义状态:

onChange={(_, value) => {
  field.onChange(value);
  setSelected(value);
}}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 08:45:09