MUI X Data Grid:onSortModelChange触发时如何获取排序后行顺序?
问题
在MUI X Data Grid中,当我在onSortModelChange事件中访问apiRef时,函数能正常调用,但使用gridSortedRowIdsSelector(apiRef)获取到的是排序前的旧行顺序。目前我通过监听stateChange来等待新顺序,这种方法十分繁琐。请问获取网格重新排序后行顺序的正确方式是什么?
当前实现代码:
useEffect(() => { let rowOrder: TOpportunity['id'][] = []; let unsubscribeState = () => {}; // 处理网格状态变化的函数 const handleStateChange: GridEventListener<'stateChange'> = () => { const newOrder = gridSortedRowIdsSelector(gridApi); // 如果1秒后行顺序没变化,就取消订阅状态变化 setTimeout(() => { unsubscribeState(); }, 1000); // 检查新顺序是否和之前的不同 if (JSON.stringify(newOrder) !== JSON.stringify(rowOrder)) { rowOrder = newOrder; // 停止监听状态变化 unsubscribeState?.(); } }; // 处理排序模型变化 const handleSortModelChange: GridEventListener<'sortModelChange'> = () => { // 记录当前的"旧"顺序,之后和"新"顺序对比 rowOrder = gridSortedRowIdsSelector(gridApi); // 订阅状态变化,直到新顺序生效 unsubscribeState = gridApi.current.subscribeEvent('stateChange', handleStateChange); }; // 订阅排序模型变化 const unsubscribeSort = gridApi.current.subscribeEvent('sortModelChange', handleSortModelChange); if (rowOrder.length === 0) { handleSortModelChange(); } // `subscribeEvent`方法会在`useEffect`的清理函数中自动取消订阅 return () => { unsubscribeState(); unsubscribeSort(); }; }, [gridApi]);
正确解决方案
你不需要通过监听stateChange来等待排序完成,MUI X Data Grid提供了更精准的rowsSorted事件——这个事件会在排序操作完成、行顺序完全更新后触发,此时直接调用gridSortedRowIdsSelector就能拿到最新的行ID顺序。
推荐使用官方提供的useGridApiEventHandler钩子订阅网格事件,替代手动在useEffect里管理订阅,代码更简洁且符合React Hooks规范:
import { useGridApiEventHandler, gridSortedRowIdsSelector } from '@mui/x-data-grid'; // 在组件内部定义处理函数 const handleRowsSorted = () => { const latestSortedRowIds = gridSortedRowIdsSelector(apiRef); // 这里拿到的就是排序后的最新行ID顺序,执行你的业务逻辑 console.log('排序后的行顺序:', latestSortedRowIds); }; // 订阅rowsSorted事件 useGridApiEventHandler(apiRef, 'rowsSorted', handleRowsSorted);
如果仍需要结合sortModelChange事件使用,也可以在事件触发后强制同步执行排序相关的异步操作(但注意该API带unstable_前缀,后续可能变更,不推荐长期依赖):
const handleSortModelChange = () => { apiRef.current.unstable_runPendingTimeouts(); const latestSortedRowIds = gridSortedRowIdsSelector(apiRef); // 此时能拿到最新排序后的行顺序 };
核心逻辑:sortModelChange是在排序模型更新时触发,但网格的行排序操作是异步执行的,所以此时调用选择器拿到的是旧数据;而rowsSorted是排序流程彻底结束后触发,能保证获取到最新的行状态。
内容的提问来源于stack exchange,提问作者Michael Seltenreich
相关产品推荐
相关产品推荐

