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

React中如何实现数据去重后映射值并正常显示label字段

问题根源

你现在遇到的label不展示、去重失效的问题,来自三个核心错误:

  • 去重逻辑完全不生效:Array.indexOf() 判断对象时是比对内存引用地址,选中事件返回的选项对象,和localizedData里定义的原始对象不是同一个引用,所以localizedData.indexOf(element) 永远返回-1,和当前遍历的index(从0开始的正整数)永远不可能相等,最终filter返回空数组,后续map自然拿不到任何label字段。
  • 组件配置和预期不符:你给MultiSelect设置的textField="value",但实际想要展示的是label字段,会导致下拉选项显示内容不符合预期。
  • 传值不一致:传给父组件的value字段直接使用了未去重的原始选中值e.target.value,会导致多选框回显重复选项,同时直接修改props.dataItem的写法违反React单向数据流规则,容易触发不可预期的渲染问题。
修复方案
  1. 去重逻辑改用唯一标识判断:基于你设置的dataItemKey: 'id'作为唯一键,用findIndex判断重复项,不要直接比对对象引用。
  2. 修正MultiSelect的textField配置为label,对齐展示需求。
  3. 移除冗余的无效for循环代码,不要直接修改props对象,基于去重后的结果生成展示值、回传选中值,同时补全组件的value属性保证编辑态回显正常。
修复后完整代码
import React from 'react';
import { MultiSelect } from '@progress/kendo-react-dropdowns';

export const SymphonyMultiSelectCell = (props) => {
  const dataItemKey = 'id';
  const textField = 'label';

  const localizedData = [
    { value: 'one', label: 'one', id: 1 },
    { value: 'two', label: 'two', id: 2 },
    { value: 'three', label: 'three', id: 3 },
    { value: 'four', label: 'four', id: 4 },
    { value: 'four', label: 'four', id: 4 },
  ];

  const onChange = (e) => {
    if (!props.onChange) return;
    const selectedValues = e.target.value;
    // 基于唯一id对选中值去重
    const uniqueSelected = selectedValues.filter((item, index, arr) => {
      return arr.findIndex(target => target[dataItemKey] === item[dataItemKey]) === index;
    });
    // 拼接label生成单元格展示文本
    const displayText = uniqueSelected.map(item => item[textField]).join(',');
    // 新建dataItem副本,避免直接修改props
    const updatedDataItem = {
      ...props.dataItem,
      [props.field]: displayText
    };

    props.onChange({
      dataIndex: 0,
      dataItem: updatedDataItem,
      field: props.field,
      syntheticEvent: e.syntheticEvent,
      value: uniqueSelected, // 回传去重后的值供组件回显
      tabIndex: 0,
    });
  };

  // 单元格进入编辑态时,把存储的逗号分隔文本转回选项对象供多选组件回显
  const selectValue = props.dataItem[props.field] 
    ? props.dataItem[props.field].split(',').map(label => {
        return localizedData.find(item => item.label === label)
      }).filter(Boolean) 
    : [];

  return (
    <td>
      <MultiSelect
        data={localizedData}
        textField={textField}
        dataItemKey={dataItemKey}
        onChange={onChange}
        value={selectValue}
      />
    </td>
  );
};

补充优化:如果你的数据源localizedData本身就存在重复项(比如示例里id为4的four出现了两次),也可以先对数据源本身做一次去重再传给MultiSelect,从源头避免重复选项可选。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 19:31:11