基于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
相关产品推荐
相关产品推荐

