Ag-Grid onSelectionChanged结合useState时复选框无法勾选问题
解决方案
问题根源
在onSelectionChanged中直接调用setSelectedRows会触发组件重渲染,Ag-Grid内部状态与React组件状态同步时出现冲突,导致复选框勾选逻辑异常。而useRef仅存储状态不触发重渲染,无法驱动工具栏、按钮等依赖状态更新的组件刷新。
修复步骤
稳定Ag-Grid API引用
用useRef保存Grid API,避免每次重渲染重新获取:const gridApi = useRef(null); const onGridReady = useCallback((params) => { gridApi.current = params.api; }, []);优化选中状态更新逻辑
用useCallback包裹onSelectionChanged,仅当选中行实际变化时更新useState,避免不必要的重渲染:const [selectedRows, setSelectedRows] = useState([]); // 自定义行比较函数(根据业务用唯一ID判断,比JSON.stringify性能更好) const isSelectedRowsChanged = (newRows, oldRows) => { if (newRows.length !== oldRows.length) return true; return !newRows.every(newRow => oldRows.some(oldRow => oldRow.id === newRow.id)); }; const onSelectionChanged = useCallback(() => { const newSelectedNodes = gridApi.current.getSelectedNodes(); const newSelectedRows = newSelectedNodes.map(node => node.data); if (isSelectedRowsChanged(newSelectedRows, selectedRows)) { setSelectedRows(newSelectedRows); } }, [selectedRows]);确保Grid配置正确
确认行选择模式和复选框列配置无误:const columnDefs = useMemo(() => [ { headerName: '选择', checkboxSelection: true, headerCheckboxSelection: true, // 可选:开启表头全选 width: 60 }, // 其他列定义 ], []); const gridOptions = useMemo(() => ({ rowSelection: 'multiple', suppressRowClickSelection: true, // 可选:仅允许复选框触发选择,避免行点击干扰 }), []);稳定数据源引用
用useMemo包裹rowData,避免组件重渲染时Grid重置内部状态:const rowData = useMemo(() => yourDataSource, [yourDataSource]);
说明
通过上述方式,既保证了选中状态能触发React组件重渲染(满足工具栏、按钮的状态更新需求),又避免了不必要的重渲染导致Ag-Grid复选框逻辑异常。如果仍有问题,检查是否存在其他导致Grid重置的因素(比如动态修改columnDefs但未用useMemo)。
内容的提问来源于stack exchange,提问作者Bishal
相关产品推荐
相关产品推荐

