React中使用AG Grid为已编辑单元格设置样式不生效问题
问题原因
你当前的实现不生效核心有两个问题:
colDef是列级全局配置,你在onCellValueChanged里动态覆盖colDef.cellClass,每次编辑都会把判断逻辑替换成「匹配最后一次编辑的行和列」,之前编辑过的单元格会直接丢失样式,且这个全局修改会影响整列所有单元格的渲染逻辑。- AG Grid不会追踪运行时直接对
colDef对象的属性修改,即使调用refreshCells也不会按你预期重新读取被篡改的配置。
正确实现方案
不要动态修改列配置,通过行节点状态标记已编辑的脏单元格,在固定的cellClass逻辑里判断当前单元格是否需要应用脏样式即可:
const defaultColDef = useMemo<ColDef>(() => { return { resizable: true, headerComponent: "customHeader", // 固定声明cellClass判断逻辑,初始化时就注册好 cellClass: (params) => { // 从行节点上取已编辑的字段集合,判断当前单元格是否属于脏单元格 const dirtyColSet = params.node?.data?.__dirtyCols ?? new Set<string>(); const currentColKey = params.colDef.field ?? params.colDef.colId ?? ""; return dirtyColSet.has(currentColKey) ? "dirty-cell" : ""; }, onCellValueChanged: ({ api, node, column }) => { if (!node?.data) return; // 初始化当前行的脏字段存储集合 if (!node.data.__dirtyCols) { node.data.__dirtyCols = new Set<string>(); } // 标记当前编辑的列为脏状态 const editedColKey = column.getColDef().field ?? column.getColId(); node.data.__dirtyCols.add(editedColKey); // 定向刷新当前编辑的单元格即可 api.refreshCells({ rowNodes: [node], columns: [column], force: true }); } }; }, []); // AgGridReact组件部分不需要做额外修改,保持原有写法即可 <AgGridReact ref={gridRef} defaultColDef={defaultColDef} onCellValueChanged={onCellChange} rowData={rows} columnDefs={columns} getRowId={param => param.data.id ?? param.data.virtual_id} components={{ customHeader: CustomHeaderCell }} onCellDoubleClicked={onCellDoubleClicked} onCellKeyDown={onCellKeyDown} rowClassRules={rowClassRules} gridOptions={{ tooltipShowDelay: 0 }} onDragStopped={onDragStopped} />
补充说明
- 如果不想污染原始业务数据,可以把脏状态存在行节点的自定义状态里,通过
node.setRowState、node.getRowState存取,判断逻辑保持一致即可。 - 记得提前声明
.dirty-cell对应的CSS样式(比如修改背景色、边框样式),否则不会有视觉效果。 - 如果后续需要清除脏样式、批量标记脏单元格,只需要操作对应行节点的脏字段集合,再调用
refreshCells刷新目标单元格即可。
内容的提问来源于stack exchange,提问作者Hud Rosli
相关产品推荐
相关产品推荐

