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}
关键修改点
自定义
handleSelectChange函数:- 接收React Select返回的选中选项数组,转换为你需要的格式(提取
value或保留完整对象) - 调用
formik.setFieldValue手动更新Formik表单中对应字段的值
- 接收React Select返回的选中选项数组,转换为你需要的格式(提取
修正
defaultValue:- React Select的
defaultValue需要是匹配选项格式的对象数组,因此将Formik中存储的value数组转换为对应的选项对象数组
- React Select的
处理
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
相关产品推荐
相关产品推荐

