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

如何在React中结合Formik实现对象数组的单选与多选Autocomplete?

在React中结合Formik实现支持单选/多选的Autocomplete组件

下面是基于Material-UI Autocomplete和Formik实现单选/多选对象数组选择的完整方案,包含代码示例和关键逻辑说明:

核心实现代码

import { Formik, Form } from 'formik';
import { Autocomplete, TextField, Chip } from '@mui/material';

// 选项数据源
const arrayOfObject = [
  { id: 1, name: "test" },
  { id: 2, name: "test1" },
  { id: 3, name: "test2" },
];

// 表单组件
const MyForm = () => {
  return (
    <Formik
      initialValues={{ userId: [] }} // 多选时初始值为数组,单选时设为null或单个ID
      onSubmit={(values) => {
        console.log('提交的表单值:', values);
      }}
    >
      {({ formik }) => (
        <Form>
          <Autocomplete
            id="userId"
            multiple // 设为false则切换为单选模式
            options={arrayOfObject}
            getOptionLabel={(option) => option.name} // 指定选项显示的文本
            onChange={(event, newValue) => {
              // 多选时提取选中项的ID数组,单选时直接取单个ID
              const selectedIds = multiple 
                ? newValue.map(item => item.id) 
                : newValue?.id || null;
              formik.setFieldValue('userId', selectedIds);
            }}
            // 根据Formik字段值反向匹配对应的完整对象,保证组件显示与表单状态一致
            value={
              multiple
                ? arrayOfObject.filter(option => formik.values.userId.includes(option.id))
                : arrayOfObject.find(option => option.id === formik.values.userId) || null
            }
            renderInput={(params) => (
              <TextField
                {...params}
                label="食材"
                variant="outlined"
                inputProps={{
                  ...params.inputProps,
                  'aria-label': '选择食材',
                }}
              />
            )}
            // 多选模式下自定义标签渲染
            renderTags={(value, getTagProps) =>
              value.map((option, index) => (
                <Chip
                  key={option.id} // 用唯一ID做key,避免index导致的渲染异常
                  label={option.name}
                  {...getTagProps({ index })}
                />
              ))
            }
            noOptionsText="未找到数据!"
          />
        </Form>
      )}
    </Formik>
  );
};

export default MyForm;

关键逻辑说明

  • 状态同步:通过onChange事件将选中对象的ID(或ID数组)同步到Formik的表单字段,确保表单存储的是业务所需的ID值,而非完整对象。
  • 值映射:value属性通过Formik字段值反向匹配数据源中的完整对象,保证Autocomplete组件的显示值与表单状态完全对齐。
  • 单选/多选切换:仅需修改multiple属性,同时调整initialValues、onChange和value的逻辑即可切换模式:
    • 单选模式:设置initialValues={{ userId: null }},onChange取newValue?.id,value用find匹配单个对象。
    • 多选模式:设置initialValues={{ userId: [] }},onChange取ID数组,value用filter匹配多个对象。
  • 细节优化:渲染标签时使用对象的唯一id作为key,避免因index变动导致的不必要重渲染。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 23:45:30