解决Mantine React Table重复Key警告及Jest测试报错问题
问题描述
使用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元素。
具体修正步骤
给重复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> ), },移除Cell内部元素的多余key
React仅在渲染数组列表时需要key,单个组件无需添加。你之前加的key不仅无效,还可能因为cell.getValue()返回对象(如attributes是对象,转成字符串为[object Object])导致新的重复问题,直接删除即可。优化按钮列配置
按钮列作为操作列,无需指定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

