From 93a58b76853e3b471fce491ce4bc330453f83bfa Mon Sep 17 00:00:00 2001 From: Andrew Cherniavskii Date: Mon, 24 Oct 2022 15:04:25 +0200 Subject: [PATCH] [DataGrid] Fix memory leak on grid unmount (#6579) --- .../src/hooks/core/useGridApiInitialization.ts | 2 ++ .../grid/x-data-grid/src/utils/createSelector.ts | 14 +++++++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/packages/grid/x-data-grid/src/hooks/core/useGridApiInitialization.ts b/packages/grid/x-data-grid/src/hooks/core/useGridApiInitialization.ts index 8e92040cdf8d..0e4613c4800e 100644 --- a/packages/grid/x-data-grid/src/hooks/core/useGridApiInitialization.ts +++ b/packages/grid/x-data-grid/src/hooks/core/useGridApiInitialization.ts @@ -4,6 +4,7 @@ import { GridSignature } from '../utils/useGridApiEventHandler'; import { DataGridProcessedProps } from '../../models/props/DataGridProps'; import { GridApiCommon, GridCoreApi } from '../../models'; import { EventManager } from '../../utils/EventManager'; +import { unstable_resetCreateSelectorCache } from '../../utils/createSelector'; const isSyntheticEvent = (event: any): event is React.SyntheticEvent => { return event.isPropagationStopped !== undefined; @@ -68,6 +69,7 @@ export function useGridApiInitialization( const api = apiRef.current; return () => { + unstable_resetCreateSelectorCache(api.instanceId); api.publishEvent('unmount'); }; }, [apiRef]); diff --git a/packages/grid/x-data-grid/src/utils/createSelector.ts b/packages/grid/x-data-grid/src/utils/createSelector.ts index 9ade06d82e0e..1897a4bb812e 100644 --- a/packages/grid/x-data-grid/src/utils/createSelector.ts +++ b/packages/grid/x-data-grid/src/utils/createSelector.ts @@ -2,8 +2,10 @@ import * as React from 'react'; import { createSelector as reselectCreateSelector, Selector, SelectorResultArray } from 'reselect'; import { buildWarning } from './warning'; +type CacheKey = number | string; + interface CacheContainer { - cache: Record> | null; + cache: Record> | null; } export interface OutputSelector { @@ -92,6 +94,12 @@ export const createSelector: CreateSelectorFunction = (...args: any) => { }; // eslint-disable-next-line @typescript-eslint/naming-convention -export const unstable_resetCreateSelectorCache = () => { - cacheContainer.cache = null; +export const unstable_resetCreateSelectorCache = (cacheKey?: CacheKey) => { + if (typeof cacheKey !== 'undefined') { + if (cacheContainer.cache && cacheContainer.cache[cacheKey]) { + delete cacheContainer.cache[cacheKey]; + } + } else { + cacheContainer.cache = null; + } };