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

ReactSelect多选输入相同值出现key重复问题的解决咨询

React Select多选组件重复值的Key重复警告解决方案

问题场景

使用React Select实现多选输入字段时,输入两个相同值后控制台出现以下警告:

Warning: Encountered two children with the same key, abc-abc. Keys should be unique so that components maintain their identity across updates.

尽管在value属性的map逻辑中为每个项添加了key:

value={(value as string[]).map((x, index) => ({ value: x, label: x, key: index }))}

但警告依然存在。

问题原因

React Select内部不会使用你在选项对象中定义的key属性,它默认通过option.value字段生成组件的key(格式为value-label)。当多个选项的value相同时,生成的key必然重复,从而触发警告。

解决方法

方法1:为每个选项添加唯一标识字段(推荐)

修改数据存储结构,为每个选项添加唯一ID,通过getOptionValue指定用该ID作为唯一识别依据:

  1. 定义选项类型(TypeScript示例):
type SelectOption = {
  id: string;
  value: string;
  label: string;
};
  1. 调整组件逻辑:
<ReactSelect
  aria-label="aria-select-field"
  styles={{
    multiValueRemove: () => ({
      display: 'flex',
      alignItems: 'center',
      color: '#516382',
      cursor: 'pointer',
    }),
    multiValue: (defaultStyles) => ({
      ...defaultStyles,
      backgroundColor: '#ebeef5',
      borderRadius: '16px',
      padding: '0 12px',
      height: '32px',
      display: 'flex',
      alignItems: 'center',
      marginTop: '3.7px',
    }),
  }}
  id={name}
  closeMenuOnSelect={false}
  placeholder={placeholder}
  components={{
    ClearIndicator: () => <span />,
    IndicatorSeparator: () => <span />,
    DropdownIndicator: () => <span />,
  }}
  getOptionValue={(option) => option.id} // 指定用唯一ID作为识别键
  value={selectedOptions} // 传入带唯一ID的选项数组
  inputValue={inputValue}
  isMulti
  menuIsOpen={false}
  isDisabled={disabled}
  onKeyDown={(e) => {
    if (e.key === 'Enter' || e.key === 'Tab') {
      const target = e.target as HTMLInputElement;
      if (target.value) {
        // 生成唯一ID,可使用Date.now()或uuid库
        const newOption = {
          id: `${target.value}-${Date.now()}`,
          value: target.value,
          label: target.value
        };
        onChange([...selectedOptions, newOption]);
        setInputValue('');
      }
      e.preventDefault();
    } else if ((e.key === 'Backspace' || e.key === 'Delete') && disableDeselect && !error) e.preventDefault();
  }}
  onInputChange={(e, actionMeta: InputActionMeta) => {
    setInputValue(e);
    if (actionMeta.action !== 'input-blur' && actionMeta.action !== 'menu-close') onFocus();
  }}
  onChange={(e) => onChange(e)} // 直接返回带ID的选项数组,后续可按需提取value
  onFocus={onFocus}
  onBlur={(e) => {
    const target = e.target as HTMLInputElement;
    if (target.value) {
      const newOption = {
        id: `${target.value}-${Date.now()}`,
        value: target.value,
        label: target.value
      };
      onChange([...selectedOptions, newOption]);
      setInputValue('');
    }
    onFocus();
  }}
/>

方法2:临时修改value为唯一值(快速修复)

如果不想调整存储结构,可以在map时将value设置为原value+索引的组合,确保唯一性:

value={(value as string[]).map((x, index) => ({ 
  value: `${x}-${index}`, // 用原value+索引生成唯一value
  label: x, 
}))}

注意:此方法会让onChange返回的value包含索引后缀,需要后续处理提取原始值。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 05:55:35