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

解决Mantine React Table重复Key警告及Jest测试报错问题

解决Mantine React Table重复Key警告问题

问题描述

使用Mantine React Table时出现重复Key警告,运行Jest测试用例时也会触发相同错误。

错误提示

Warning: Encountered two children with the same key, 0_attributes() => row.getValue(columnId). Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.

相关组件代码

export const CreatorLookupsTable = ({
  isLoading,
  tableData,
  error,
  limit,
  addCreator,
}: Props) => {
  const data = tableData.data;

  const ErrorOrNoResult = () => {
    return limit
      ? ''
      : error
      ? 'Search results will be shown here.'
      : Object.keys(data).length === 0
      ? 'No creators found. Check username spelling and/or platform chosen.'
      : 'No creators found.';
  };

  const columns = [
    {
      accessorKey: 'attributes.method',
      header: 'Source',
      enableSorting: true,
      Cell: ({ cell, rowIndex }: any) => (
        <p
          key={`source-${cell.getValue()}-${rowIndex}`}
          style={{
            color: '#5E5ADB',
            margin: '0px',
            textTransform: 'capitalize',
          }}
        >
          {cell.getValue()}
        </p>
      ),
    },
    {
      accessorKey: 'attributes',
      header: 'Creators',
      enableSorting: true,
      Cell: ({ renderedCellValue, cell, rowIndex }: any) => (
        <Box
          key={`creators-${cell.getValue()}-${rowIndex}`}
          sx={{
            display: 'flex',
            alignItems: 'center',
          }}
        >
          <Avatar
            src={renderedCellValue[renderedCellValue.method]?.logo}
            size={20}
            radius={100}
            sx={{
              marginRight: '5px',
            }}
          />
          <p>{renderedCellValue[renderedCellValue.method]?.displayName}</p>
        </Box>
      ),
    },
    {
      accessorKey: 'attributes',
      header: 'Reach',
      enableSorting: true,
      Cell: ({ renderedCellValue, cell, rowIndex }: any) => (
        <span
          key={`reach-${cell.getValue()}-${rowIndex}`}
          style={{
            display: 'flex',
            justifyContent: 'center',
            alignItems: 'center',
            width: '50px',
            backgroundColor: '#F4F4F5',
            borderRadius: '16px',
            padding: '2px 8px ',
            fontWeight: 400,
          }}
        >
          {formatLargeNumber(
            renderedCellValue[renderedCellValue.method]?.statistics.views
          )}
        </span>
      ),
    },
    {
      accessorKey: 'videos',
      header: 'Videos',
      enableSorting: true, // disable sorting for this column
      Cell: ({ cell, rowIndex }: any) => (
        <span
          key={`videos-${cell.getValue()}-${rowIndex}`}
          style={{
            color: '#3538CD',
            display: 'flex',
            justifyContent: 'center',
            width: '50px',
            alignItems: 'center',
            padding: '2px 8px ',
            backgroundColor: '#EEF4FF',
            borderRadius: '16px',
            fontWeight: 400,
          }}
        >
          {formatLargeNumber(cell.getValue() as number)}
        </span>
      ),
    },
    {
      id: 'button',
      header: '',
      enableSorting: false,
      Cell: ({ cell, rowIndex }: any) => (
        <Button
          key={`add-${cell.getValue()}-${rowIndex}`}
          style={{
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'center',
            width: '40px',
            height: '16px',
            backgroundColor: '#6FCF97',
            fontSize: '8px',
            textTransform: 'uppercase',
            fontFamily: 'Alegreya Sans',
            fontWeight: 700,
          }}
          // onClick={() => addCreator()}
        >
          add
        </Button>
      ),
    },
  ];

  const table = useMantineReactTable({
    columns,
    data,
    enableSorting: true,
    enableColumnActions: false,
    enableColumnFilters: false,
    enablePagination: false,
    enableFullScreenToggle: false,
    enableDensityToggle: false,
    enableHiding: false,
    enableGlobalFilter: false,
    state: {
      isLoading: isLoading,
    },
    mantinePaperProps: {
      sx: (theme) => ({
        border: '0px solid !important',
      }),
    },
    mantineTableHeadCellProps: {
      sx: {
        fontFamily: '__Alegreya_Sans_d501ea',
        fontSize: '14px',
        fontStyle: 'normal',
        fontWeight: 400,
        lineHeight: '20px',
        textTransform: 'uppercase',
        padding: '0px 10px !important',
      },
    },
    mantineTableBodyCellProps: {
      sx: {
        padding: '0px 10px !important',
        fontFamily: '__Alegreya_Sans_d501ea',
      },
    },
    localization: {
      noRecordsToDisplay: ErrorOrNoResult(),
    },
  });

  return (
    <div data-testid={'creator-table-test-id'}>
      <MantineReactTable table={table} />
    </div>
  );
};

修正方案

问题根源

你有两列共用了同一个accessorKey: 'attributes',Mantine React Table会基于accessorKey生成内部单元格Key,这直接导致了重复Key警告。你给Cell内部元素加key无效,因为警告来自表格的内部渲染逻辑,而非你自定义的Cell元素。

具体修正步骤

  1. 给重复accessorKey的列添加唯一id
    给Creators和Reach列分别指定唯一id,让表格能生成唯一的内部Key:

    {
      accessorKey: 'attributes',
      id: 'creators-column', // 新增唯一列id
      header: 'Creators',
      enableSorting: true,
      Cell: ({ renderedCellValue }: any) => (
        <Box
          sx={{
            display: 'flex',
            alignItems: 'center',
          }}
        >
          <Avatar
            src={renderedCellValue[renderedCellValue.method]?.logo}
            size={20}
            radius={100}
            sx={{
              marginRight: '5px',
            }}
          />
          <p>{renderedCellValue[renderedCellValue.method]?.displayName}</p>
        </Box>
      ),
    },
    {
      accessorKey: 'attributes',
      id: 'reach-column', // 新增唯一列id
      header: 'Reach',
      enableSorting: true,
      Cell: ({ renderedCellValue }: any) => (
        <span
          sx={{
            display: 'flex',
            justifyContent: 'center',
            alignItems: 'center',
            width: '50px',
            backgroundColor: '#F4F4F5',
            borderRadius: '16px',
            padding: '2px 8px ',
            fontWeight: 400,
          }}
        >
          {formatLargeNumber(
            renderedCellValue[renderedCellValue.method]?.statistics.views
          )}
        </span>
      ),
    },
    
  2. 移除Cell内部元素的多余key
    React仅在渲染数组列表时需要key,单个组件无需添加。你之前加的key不仅无效,还可能因为cell.getValue()返回对象(如attributes是对象,转成字符串为[object Object])导致新的重复问题,直接删除即可。

  3. 优化按钮列配置
    按钮列作为操作列,无需指定accessorKey,仅保留唯一id即可,同时可以通过行数据生成更可靠的操作逻辑:

    {
      id: 'button-column', // 明确唯一列id
      header: '',
      enableSorting: false,
      Cell: ({ row }: any) => (
        <Button
          style={{
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'center',
            width: '40px',
            height: '16px',
            backgroundColor: '#6FCF97',
            fontSize: '8px',
            textTransform: 'uppercase',
            fontFamily: 'Alegreya Sans',
            fontWeight: 700,
          }}
          onClick={() => addCreator(row.original)} // 传递当前行数据
        >
          add
        </Button>
      ),
    },
    

总结

核心解决点是确保每一列拥有唯一的标识(accessorKey或id),Mantine React Table会基于这些标识生成内部唯一Key,从根源消除重复警告。Cell内部单个元素不需要额外添加key。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 23:10:55