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

基于Formik的MUI多选Select组件提交异常及显示问题求助

解决Formik中MUI多选Select的取值与显示问题

你当前的核心问题是Formik表单状态和MUI组件状态脱节:原代码维护了独立的personName状态,导致提交时Formik无法获取选中值;改成绑定Formik的values.usersId后,又因为Checkbox的判断逻辑没同步调整,导致选中状态不显示。下面是完整的修正方案:

修正后的完整代码

/*(...)*/

// 你的Schema和初始值定义是正确的,数组类型校验符合需求
const projectSchema = yup.object().shape({
  usersId: yup.array().of(yup.string()),
});

const initialValuesProject = {
  usersId: [],
};

const ITEM_HEIGHT = 48;
const ITEM_PADDING_TOP = 8;
const MenuProps = {
  PaperProps: {
    style: {
      maxHeight: ITEM_HEIGHT * 4.5 + ITEM_PADDING_TOP,
      width: 250,
    },
  },
};

const Calendar = () => {
  // 移除多余的personName独立状态,完全复用Formik的表单状态
  const { data } = useGetAllUsersQuery();

  /*(...)*/

  return (
    /*(...)*/
    <Formik
      onSubmit={handleFormSubmit}
      initialValues={initialValuesProject}
      validationSchema={projectSchema}
    >
      {/* 解构Formik提供的核心方法 */}
      {({ values, handleSubmit, setFieldValue }) => (
        <form onSubmit={handleSubmit}>
          <FormControl size="small" sx={{ m: 1 }}>
            <Select
              id="encargadoP"
              multiple
              // 直接绑定Formik的表单字段值
              value={values.usersId}
              // 自定义onChange,用setFieldValue同步更新Formik状态
              onChange={(event) => {
                const { value } = event.target;
                // 保留自动填充的字符串处理逻辑
                const selectedValues = typeof value === "string" ? value.split(",") : value;
                setFieldValue("usersId", selectedValues);
              }}
              MenuProps={MenuProps}
              renderValue={(selected) => selected.join(", ")}
              sx={{ width: 205 }}
            >
              {data?.map(({ _id, name }) => (
                <MenuItem key={_id} value={name}>
                  {/* 基于Formik的values判断选中状态 */}
                  <Checkbox checked={values.usersId.includes(name)} />
                  <ListItemText primary={name} />
                </MenuItem>
              ))}
            </Select>
          </FormControl>
        </form>
      )}
    </Formik>
  );
};

export default Calendar;

关键修改说明

  1. 移除独立状态:删掉personName相关的useState和自定义handleChange,不再维护组件内部的独立状态,完全依赖Formik的values.usersId
  2. 绑定Formik字段:Select的value直接设为values.usersId,确保组件显示内容和Formik表单状态完全一致
  3. 同步更新Formik状态:在Select的onChange中使用Formik提供的setFieldValue方法更新usersId字段,同时保留自动填充的字符串处理逻辑
  4. 修正选中判断:Checkbox的checked属性改为判断values.usersId.includes(name),确保选中状态和Formik的表单值同步

额外优化建议

如果业务需要存储用户的_id而非name(更规范的后端交互做法),只需要做两处调整:

  • 将MenuItem的value改为_id:<MenuItem key={_id} value={_id}>
  • 渲染选中值时根据_id映射回用户名:
    renderValue={(selectedIds) => 
      selectedIds.map(id => data.find(user => user._id === id)?.name).join(", ")
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 11:42:31