From 6805c78bd0076b9e7fc0edcceb3aa2c75e6a6cb1 Mon Sep 17 00:00:00 2001 From: sai6855 Date: Fri, 10 Oct 2025 16:57:50 +0530 Subject: [PATCH 1/3] fix --- .../hooks/features/sorting/useGridSorting.ts | 26 ++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/packages/x-data-grid/src/hooks/features/sorting/useGridSorting.ts b/packages/x-data-grid/src/hooks/features/sorting/useGridSorting.ts index a40c01f7bd4b1..b6e89c7fb9631 100644 --- a/packages/x-data-grid/src/hooks/features/sorting/useGridSorting.ts +++ b/packages/x-data-grid/src/hooks/features/sorting/useGridSorting.ts @@ -373,15 +373,35 @@ export const useGridSorting = ( * 1ST RENDER */ useFirstRender(() => { - apiRef.current.applySorting(); + // When using controlled sortModel, skip calling applySorting here + // The useEnhancedEffect below will handle it after the component mounts + // This ensures proper initialization order with features like aggregation + if (props.sortModel === undefined) { + apiRef.current.applySorting(); + } }); /** * EFFECTS */ + const isFirstEffect = React.useRef(true); useEnhancedEffect(() => { if (props.sortModel !== undefined) { - apiRef.current.setSortModel(props.sortModel); + const currentModel = gridSortModelSelector(apiRef); + // On first render with controlled sortModel, always call setSortModel + // to ensure aggregation and other features get the correct sorted state + if (isFirstEffect.current) { + isFirstEffect.current = false; + // Always call setSortModel on first render to trigger applySorting + apiRef.current.setState( + mergeStateWithSortModel(props.sortModel, props.disableMultipleColumnsSorting), + ); + apiRef.current.applySorting(); + } else if (currentModel !== props.sortModel) { + apiRef.current.setSortModel(props.sortModel); + } + } else { + isFirstEffect.current = false; } - }, [apiRef, props.sortModel]); + }, [apiRef, props.sortModel, props.disableMultipleColumnsSorting]); }; From 29e6659f65ba96afcec2f0f44276543504430bc8 Mon Sep 17 00:00:00 2001 From: sai6855 Date: Fri, 10 Oct 2025 17:40:42 +0530 Subject: [PATCH 2/3] fix --- .../features/aggregation/useGridAggregation.ts | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/packages/x-data-grid-premium/src/hooks/features/aggregation/useGridAggregation.ts b/packages/x-data-grid-premium/src/hooks/features/aggregation/useGridAggregation.ts index 0a91e751dc037..571a6f141723a 100644 --- a/packages/x-data-grid-premium/src/hooks/features/aggregation/useGridAggregation.ts +++ b/packages/x-data-grid-premium/src/hooks/features/aggregation/useGridAggregation.ts @@ -88,6 +88,7 @@ export const useGridAggregation = ( ); const abortControllerRef = React.useRef(null); + const hasAppliedAggregationRef = React.useRef(false); const applyAggregation = React.useCallback( (reason?: 'filter' | 'sort') => { // Abort previous if any @@ -106,7 +107,11 @@ export const useGridAggregation = ( const aggregatedFields = Object.keys(aggregationRules); const currentAggregationLookup = gridAggregationLookupSelector(apiRef); const needsSorting = shouldApplySorting(aggregationRules, aggregatedFields); - if (reason === 'sort' && !needsSorting) { + // Only skip re-applying aggregation if: + // 1. This is triggered by a sort event + // 2. None of the aggregated columns need sorting + // 3. Aggregation has been applied at least once before + if (reason === 'sort' && !needsSorting && hasAppliedAggregationRef.current) { // no need to re-apply aggregation on `sortedRowsSet` if sorting is not needed return; } @@ -148,6 +153,7 @@ export const useGridAggregation = ( apiRef.current.applySorting(); } abortControllerRef.current = null; + hasAppliedAggregationRef.current = true; return; } @@ -198,6 +204,7 @@ export const useGridAggregation = ( ...state, aggregation: { ...state.aggregation, lookup: {} }, })); + hasAppliedAggregationRef.current = true; } }, [ @@ -281,6 +288,12 @@ export const useGridAggregation = ( useGridEvent(apiRef, 'columnsChange', checkAggregationRulesDiff); useGridEvent(apiRef, 'filteredRowsSet', deferredApplyAggregation); useGridEvent(apiRef, 'sortedRowsSet', () => deferredApplyAggregation('sort')); + useGridEvent(apiRef, 'rowsSet', () => { + // Reset the flag so that subsequent aggregation (even from sort) will run + // This ensures aggregation recalculates when rows load asynchronously + hasAppliedAggregationRef.current = false; + deferredApplyAggregation(); + }); /** * EFFECTS From 970784eabde61bfeea43943546024f7054709208 Mon Sep 17 00:00:00 2001 From: sai6855 Date: Fri, 10 Oct 2025 17:42:49 +0530 Subject: [PATCH 3/3] fix --- .../hooks/features/sorting/useGridSorting.ts | 26 +++---------------- 1 file changed, 3 insertions(+), 23 deletions(-) diff --git a/packages/x-data-grid/src/hooks/features/sorting/useGridSorting.ts b/packages/x-data-grid/src/hooks/features/sorting/useGridSorting.ts index b6e89c7fb9631..a40c01f7bd4b1 100644 --- a/packages/x-data-grid/src/hooks/features/sorting/useGridSorting.ts +++ b/packages/x-data-grid/src/hooks/features/sorting/useGridSorting.ts @@ -373,35 +373,15 @@ export const useGridSorting = ( * 1ST RENDER */ useFirstRender(() => { - // When using controlled sortModel, skip calling applySorting here - // The useEnhancedEffect below will handle it after the component mounts - // This ensures proper initialization order with features like aggregation - if (props.sortModel === undefined) { - apiRef.current.applySorting(); - } + apiRef.current.applySorting(); }); /** * EFFECTS */ - const isFirstEffect = React.useRef(true); useEnhancedEffect(() => { if (props.sortModel !== undefined) { - const currentModel = gridSortModelSelector(apiRef); - // On first render with controlled sortModel, always call setSortModel - // to ensure aggregation and other features get the correct sorted state - if (isFirstEffect.current) { - isFirstEffect.current = false; - // Always call setSortModel on first render to trigger applySorting - apiRef.current.setState( - mergeStateWithSortModel(props.sortModel, props.disableMultipleColumnsSorting), - ); - apiRef.current.applySorting(); - } else if (currentModel !== props.sortModel) { - apiRef.current.setSortModel(props.sortModel); - } - } else { - isFirstEffect.current = false; + apiRef.current.setSortModel(props.sortModel); } - }, [apiRef, props.sortModel, props.disableMultipleColumnsSorting]); + }, [apiRef, props.sortModel]); };