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

React Select多选组件结合Formik无法正确返回数组值问题求助

问题解决:React Select多选组件在Formik中无法正确返回数组值

问题分析

你在模态框中使用React Select多选组件时,前端显示正常,但通过Formik提交表单时无法正确获取选中值的数组格式,而普通输入框(descricao)功能正常。核心原因是Formik默认的handleChange适配标准HTML输入组件的事件结构,而React Select的onChange返回的是选中的选项对象/数组,并非标准event对象,直接绑定formik.handleChange无法正确更新Formik的表单状态。

解决方案

修改React Select组件配置,通过自定义onChange函数结合Formik的setFieldValue手动更新表单值,同时确保初始值与选中值格式匹配:

修改后的完整代码

import clsx from 'clsx'
import Axios from "axios";
import React from "react";
import 'react-notifications-component/dist/theme.css'
import { Store } from 'react-notifications-component';
import { useFormik } from 'formik';
import Select from "react-select";

const Modal_cadastra = ({close}) => {

  const cities = [
    {label: 'New York1', value: 'NY'},
    {label: 'Rome', value: 'RM'},
    {label: 'London', value: 'LDN'},
    {label: 'Istanbul', value: 'IST'},
    {label: 'Paris', value: 'PRS'}
];

    const formik = useFormik({
      initialValues: {
        atividades: {
          atividades_id: [],
        },
        descricao: '',
      },
      onSubmit: values => {
        alert(JSON.stringify(values, null, 2));
      },
    });

    // 自定义React Select的选中事件处理
    const handleSelectChange = (selectedOptions) => {
      // 提取选中项的value组成数组,若需完整对象则直接传selectedOptions
      const selectedValues = selectedOptions ? selectedOptions.map(opt => opt.value) : [];
      formik.setFieldValue('atividades.atividades_id', selectedValues);
    }

    return (
        <>
        <form id='kt_modal_add_user_form' onSubmit={formik.handleSubmit} className='form' noValidate>
          <div
            className='modal fade show d-block modal-open'
            id='kt_modal_add_user'
            role='dialog'
            tabIndex={-1}
            aria-modal='true'
          >
            <div className='modal-dialog modal-dialog-centered mw-650px'>
              <div className='modal-content'>
                <div className='modal-header'>
                  <h2 className='fw-bolder'>Cadastrar tipo mão de obra</h2>
                  <div
                    className='btn btn-icon btn-sm btn-active-icon-primary'
                    data-kt-users-modal-action='close'
                    style={{cursor: 'pointer'}}
                    onClick={close}
                  >    
                  </div>     
                </div>
                <div className='modal-body scroll-y mx-5 mx-xl-15 my-7'>
                  <div className='col-lg-10 fv-row'>
                    <Select
                      // 初始值需转换为React Select要求的选项对象数组
                      defaultValue={formik.values.atividades.atividades_id.map(val => cities.find(city => city.value === val))}
                      onBlur={() => formik.setFieldTouched('atividades.atividades_id', true)}
                      onChange={handleSelectChange}
                      isMulti
                      options={cities}
                      className="basic-multi-select"
                      classNamePrefix="select"  
                    />
                  </div>

                  <div className='fv-row mb-7'>
                    <label className='fw-bold fs-6 mb-2'>TIPO MÃO DE OBRA</label>
                    <input
                      placeholder='Tipo mão de obra'
                      type='text'
                      name='descricao'
                      id='descricao'
                      className={clsx(
                        'form-control form-control-solid mb-3 mb-lg-0',
                      )}
                      autoComplete='off'
                      disabled={false}
                      onChange={formik.handleChange}
                      value={formik.values.descricao}
                    />
                  </div>
                </div>
  
                <div className='fv-row mb-7'>
                  <div className='text-center'>
                    <button
                      type='reset'
                      className='btn btn-light me-3'
                      data-kt-users-modal-action='cancel'
                      onClick={close}
                    >
                      Sair
                    </button>
    
                    <button
                      type='submit'
                      className='btn btn-primary'
                      data-kt-users-modal-action='submit'
                    >
                      <span className='indicator-label'>Salvar</span>
                    </button>
                  </div>
                </div>
              </div>
            </div>
          </div>
          <div className='modal-backdrop fade show'></div>
        </form>
        </>
      )
    }
 
export {Modal_cadastra}

关键修改点

  1. 自定义handleSelectChange函数:

    • 接收React Select返回的选中选项数组,转换为你需要的格式(提取value或保留完整对象)
    • 调用formik.setFieldValue手动更新Formik表单中对应字段的值
  2. 修正defaultValue:

    • React Select的defaultValue需要是匹配选项格式的对象数组,因此将Formik中存储的value数组转换为对应的选项对象数组
  3. 处理onBlur事件:

    • 手动调用formik.setFieldTouched标记字段为已触碰,确保Formik表单验证(若有)正常工作

额外说明

如果需要保存完整的选项对象(而非仅value),只需修改handleSelectChange函数:

const handleSelectChange = (selectedOptions) => {
  formik.setFieldValue('atividades.atividades_id', selectedOptions || []);
}

此时初始值保持为空数组即可,defaultValue可直接使用formik.values.atividades.atividades_id。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 07:15:41