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

Formik SetField无法更新数组值,Material UI Autocomplete初始化异常

问题描述

我从API获取的数据格式为otherLanguages:[{code:EN,name:"English"},{code:MD,name:"Mandarin"}],尝试将其赋值给Formik的initialValues来初始化Material UI Autocomplete组件。但发现该组件似乎仅接受[{value:"EN",label:"English"},{value:"MD",label:"Mandarin"}]格式的数据,请问是否需要转换数据格式?另外配置如下Autocomplete组件后,初始值始终无法更新,从Formik初始状态设置组件值时还会报错,尝试处理事件也无效果:

<Autocomplete
    getOptionLabel={(option: { label: any; }) => option.label}
    getOptionSelected={(option: { title: string; }) => option.title === 'dull'}
    id="tags-standard"
    multiple
    onChange={(e)=>{console.log(e.target)}}
    options={countryLanguages}
    popupIcon={<ExpandMoreIcon />}
    renderInput={(params: any) => (
        <>
        <Label color={Colors.Grey900} fontSize="16px"  value="Other Languages"/>
        <StyledTextField
        {...params}
        InputProps={{
            ...params.InputProps,
            endAdornment: (
                <InputAdornment position="start"></InputAdornment>
            )
        }}
        variant="standard"
        />
        </>
    )}
    value={formik.values.otherLanguages}
/>
解决方案

一、数据格式处理:无需强制转换,适配即可

Material UI Autocomplete并不强制要求选项必须是{value, label}格式,只要通过getOptionLabel和getOptionSelected两个属性正确映射你的数据字段就行:

  • getOptionLabel:用来指定选项显示的文本,对应你的name字段
  • getOptionSelected:用来判断选中项与选项是否匹配,对应你的唯一标识code字段

如果你偏好统一成{value, label}格式,也可以提前转换数据:

// 转换API返回的数据
const convertedLanguages = otherLanguages.map(item => ({
  value: item.code,
  label: item.name
}));

转换后直接用这个数组作为options,同时Formik的initialValues.otherLanguages也要用转换后的格式(比如[{value: 'EN', label: 'English'}])。

二、修复Autocomplete组件的配置问题

你的组件有几个关键错误导致初始值失效、报错和事件无响应,逐个修正:

  1. 修正getOptionLabel和getOptionSelected
    这两个函数的参数类型和逻辑完全错误,改成和你的数据结构匹配:

    getOptionLabel={(option) => option.name} // 用name作为显示文本
    getOptionSelected={(option, selectedOption) => option.code === selectedOption.code} // 用code判断选项是否匹配
    
  2. 修正onChange事件,同步Formik状态
    Autocomplete的onChange参数是(event, newValue),不是普通的input事件,需要手动调用Formik的setFieldValue来更新状态:

    onChange={(e, newValue) => {
      formik.setFieldValue('otherLanguages', newValue);
    }}
    
  3. 确保Formik初始值格式正确
    因为组件是multiple多选模式,initialValues.otherLanguages必须是数组,且数组项的格式要和options一致:

    // Formik的initialValues示例
    initialValues: {
      otherLanguages: [] // 空数组表示初始无选中,或者放API返回的特定项比如[{code: 'EN', name: 'English'}]
    }
    
  4. 移除错误的InputProps覆盖
    你覆盖了params.InputProps.endAdornment为空,这会导致Autocomplete的默认下拉图标失效,直接去掉这个覆盖即可:

    <StyledTextField
      {...params}
      variant="standard"
    />
    

修正后的完整组件代码

<Autocomplete
    getOptionLabel={(option) => option.name}
    getOptionSelected={(option, selectedOption) => option.code === selectedOption.code}
    id="tags-standard"
    multiple
    onChange={(e, newValue) => formik.setFieldValue('otherLanguages', newValue)}
    options={countryLanguages}
    popupIcon={<ExpandMoreIcon />}
    renderInput={(params) => (
        <>
            <Label color={Colors.Grey900} fontSize="16px" value="Other Languages" />
            <StyledTextField
                {...params}
                variant="standard"
            />
        </>
    )}
    value={formik.values.otherLanguages}
/>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 13:04:54