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

基于Formik与React Hooks实现下拉菜单多选功能的问题咨询

代码调整方案

1. 调整Formik初始值配置

首先需要把表单中对应用户组的字段初始值设置为数组类型,原有的单值类型无法支持多选数据存储:

// Formik 初始化示例
const formik = useFormik({
  initialValues: {
    // 原有单值写法:groupId: ''
    groupIds: [] // 改为数组,初始为空
  },
  // 若使用Yup做校验,同步调整校验规则为数组校验
  validationSchema: Yup.object({
    groupIds: Yup.array().min(1, '至少选择一个用户组').required('请选择用户组')
  })
})

2. 修改UserAdd组件的Field配置

给Field添加multiple属性,同步对应上一步修改的字段名:

<div>
  <Field
    options={groups}
    label="Groups"
    name="groupIds" // 和初始值的字段名保持一致
    component={SelectFormField}
    keyName='groupId'
    valueName='groupName'
    multiple // 新增多选属性
  />
</div>

3. 重构SelectFormField组件

修正原有语法错误,添加多选适配逻辑:

  • 移除op.[keyName]的多余点号,修正为合法对象取值语法
  • 为Select添加renderValue属性,自定义多选时的选中项展示逻辑
  • 补充label和Select的id关联,避免文字重叠

修改后的完整代码如下:

import { getIn } from "formik";
import React from "react";
import {
  FormControl,
  InputLabel,
  Select,
  MenuItem,
  FormHelperText
} from "@material-ui/core";

export const SelectFormField = ({ field, form, label, options, keyName, valueName, ...props }) => {
  const errorText = getIn(form.touched, field.name) && getIn(form.errors, field.name);
  // 生成唯一id用于label和Select关联
  const fieldId = `select-${field.name}`;

  // 多选时自定义展示选中的组名
  const renderSelectedValue = (selected) => {
    if (!Array.isArray(selected) || selected.length === 0) return "";
    return selected
      .map(id => options.find(op => op[keyName] === id)?.[valueName])
      .filter(Boolean)
      .join("、");
  };

  return (
    <FormControl fullWidth error={!!errorText}>
      {label && <InputLabel id={fieldId}>{label}</InputLabel>}
      <Select
        fullWidth
        labelId={fieldId}
        id={fieldId}
        renderValue={props.multiple ? renderSelectedValue : undefined}
        {...field}
        {...props}
      >
        {options.map(op => (
          <MenuItem key={op[keyName]} value={op[keyName]}>
            {op[valueName]}
          </MenuItem>
        ))}
      </Select>
      <FormHelperText>{errorText}</FormHelperText>
    </FormControl>
  );
};

修改完成后点击下拉框即可按住Ctrl(Windows)/Command(Mac)多选选项,选中的值会以数组形式存储到Formik对应的字段中。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 04:54:04