React集成Ag-Grid:如何实现重复行的对比高亮及无ID数据的去重?
React Ag-Grid: 重复行高亮 + 无ID数据去重实现方案
嘿,针对你这个Ag-Grid的需求,我分两部分给你梳理实现思路,都是可以直接落地的代码方案:
一、识别并高亮带ID的重复行
首先得先给重复行打上标记,再利用Ag-Grid的行样式配置实现高亮。
1. 给重复行添加标记
我们可以通过拼接id、name、desc(如果你的实际字段是description记得替换)生成唯一键,统计每个键出现的次数,次数大于1的就是重复行:
// 生成带重复标记的数据源 const markDuplicateRows = (rows) => { // 用id+name+desc生成唯一标识键 const getRowKey = (row) => `${row.id}-${row.name}-${row.desc}`; // 统计每个键的出现次数 const rowCountMap = rows.reduce((counts, row) => { if (row.id !== undefined) { // 只处理带ID的行 const key = getRowKey(row); counts[key] = (counts[key] || 0) + 1; } return counts; }, {}); // 给每行加上isDuplicate标记 return rows.map(row => { if (row.id !== undefined) { const key = getRowKey(row); return { ...row, isDuplicate: rowCountMap[key] > 1 }; } return row; }); }; // 测试你的示例数据 const originalValues = [ { id: 10, name: 'axel', desc: 'it\'s me' }, { id: 10, name: 'axel', desc: 'not me' }, { id: 11, name: 'payton', desc: 'hello I\'m payton'}, { id: 10, name: 'axel', desc: 'it\'s me' } ]; const markedRows = markDuplicateRows(originalValues);
2. 在Ag-Grid中配置高亮样式
用Ag-Grid的getRowStyle属性,根据isDuplicate标记设置高亮背景色:
import { AgGridReact } from 'ag-grid-react'; import 'ag-grid-community/styles/ag-grid.css'; import 'ag-grid-community/styles/ag-theme-alpine.css'; // 组件内使用 const MyGrid = () => { const [rowData, setRowData] = useState(markedRows); const columnDefs = [ { field: 'id', headerName: 'ID' }, { field: 'name', headerName: 'Name' }, { field: 'desc', headerName: 'Description' } ]; return ( <div className="ag-theme-alpine" style={{ height: 400, width: 600 }}> <AgGridReact rowData={rowData} columnDefs={columnDefs} getRowStyle={(params) => { // 重复行设置浅黄色高亮,可自定义样式 return params.data.isDuplicate ? { backgroundColor: '#fff3cd' } : null; }} /> </div> ); };
这样那两行完全重复的id=10, name=axel, desc=it's me就会被高亮出来了。
二、处理无ID的新数据:自动去重
对于后续插入的不含id的对象,我们要在添加到数据源前过滤掉name和desc都重复的项:
实现去重合并函数
这个函数会把新数据和现有数据合并,同时过滤掉无ID的重复项:
const mergeAndDeduplicateRows = (existingRows, newRows) => { // 先收集现有无ID行的name+desc组合,避免重复添加 const existingNonIdKeys = new Set(); existingRows.forEach(row => { if (row.id === undefined) { existingNonIdKeys.add(`${row.name}-${row.desc}`); } }); // 过滤新数据:无ID的行只保留不在现有集合里的 const filteredNewRows = newRows.filter(row => { if (row.id === undefined) { const key = `${row.name}-${row.desc}`; if (!existingNonIdKeys.has(key)) { existingNonIdKeys.add(key); return true; } return false; } // 带ID的行直接保留,后续由重复标记处理 return true; }); // 合并后重新标记重复行 const combinedRows = [...existingRows, ...filteredNewRows]; return markDuplicateRows(combinedRows); }; // 使用示例:假设要插入这些新数据 const newRowsToAdd = [ { name: 'axel', desc: 'it\'s me' }, { name: 'new user', desc: 'first time here' }, { name: 'axel', desc: 'it\'s me' } // 这个重复项会被过滤掉 ]; // 更新数据源 const updatedRowData = mergeAndDeduplicateRows(rowData, newRowsToAdd); setRowData(updatedRowData);
额外提示
- 如果你的字段名是
description而不是desc,记得把所有代码里的desc替换成description。 - 高亮样式可以完全自定义,比如改成淡粉色、加边框,或者只高亮特定单元格(用
cellStyle代替getRowStyle)。 - 如果是实时编辑数据的场景,可以把标记重复行的逻辑放到
useEffect里,监听rowData变化,自动更新标记。
内容的提问来源于stack exchange,提问作者Austin
相关产品推荐
相关产品推荐

