如何将Material UI多选Select组件与Formik集成?
解决Material UI多选Select与Formik集成时无法获取选中值的问题
你的核心问题是没有将Select的选中状态与Formik的表单状态同步,同时存在Select值类型不匹配的问题,导致Formik无法追踪选中内容。以下是具体修正方案:
问题分析
- 你用React本地
state(personName)管理选中项,但Formik的values完全独立于这个本地状态,提交时自然拿不到数据。 - Select的
value是对象数组,但MenuItem的value是字符串(FullName),类型不匹配会导致MUI的Select内部状态异常。 - 自定义的
handleChange仅更新本地state,未同步到Formik的字段值。
修正步骤
- 移除本地state,改用Formik的
initialValues初始化选中项 - 统一Select和MenuItem的value类型(建议用用户id,更高效且避免重名问题)
- 修改
handleChange逻辑,直接通过Formik的setFieldValue更新表单字段 - 调整Select的
renderValue和MenuItem渲染,匹配value类型
完整修正代码
import { FormControl, InputLabel, ListItemText, MenuItem, OutlinedInput, Select, Button, } from '@mui/material'; import React from 'react'; import { Formik } from 'formik'; export default function Notifications() { const usersList = [ { id: 1, FullName: 'Name1' }, { id: 2, FullName: 'Name2' }, { id: 3, FullName: 'Name3' }, { id: 4, FullName: 'Name4' }, { id: 5, FullName: 'Name5' }, ]; // 初始选中项的id数组,对应Formik的initialValues const initialSelectedIds = [2, 4]; const submit = values => { // 可以根据id数组获取完整用户对象,或者直接提交id数组 const selectedUsers = usersList.filter(u => values.selectedUsers.includes(u.id)); console.log('选中的用户对象:', selectedUsers); console.log('Formik values:', values); }; const handleChange = (event, setFieldValue) => { // event.target.value是选中的id数组(因为MenuItem的value设为了id) setFieldValue('selectedUsers', event.target.value); }; return ( <Formik initialValues={{ selectedUsers: initialSelectedIds }} onSubmit={submit} > {({ values, setFieldValue }) => ( <div> <FormControl sx={{ m: 1, width: 210 }} size="small"> <InputLabel id="demo-multiple-checkbox-label">Users</InputLabel> <Select labelId="demo-multiple-checkbox-label" id="demo-multiple-checkbox" multiple // 用Formik的values作为Select的value,类型是id数组 value={values.selectedUsers} // 把setFieldValue传给handleChange onChange={(e) => handleChange(e, setFieldValue)} input={<OutlinedInput label="Users" />} renderValue={(selectedIds) => { // 根据id数组渲染选中的用户名 return selectedIds.map((id, index) => ( <span key={index} style={{ marginRight: 8 }}> {usersList.find(u => u.id === id).FullName} </span> )); }} > {usersList.map((user) => ( <MenuItem key={user.id} value={user.id}> <ListItemText primary={user.FullName} /> </MenuItem> ))} </Select> <Button variant="contained" color="primary" type="submit"> Submit </Button> </FormControl> </div> )} </Formik> ); }
关键说明
- Formik初始化:通过
initialValues设置初始选中的用户id数组,替代原来的本地state。 - 值类型统一:MenuItem的
value设为用户id(数字类型),Select的value对应Formik中的id数组,避免类型不匹配问题。 - 状态同步:
handleChange直接调用Formik的setFieldValue更新selectedUsers字段,确保Formik能追踪选中状态。 - 渲染优化:
renderValue根据id数组获取对应的用户名,渲染更简洁。
内容的提问来源于stack exchange,提问作者Jess
相关产品推荐
相关产品推荐

