Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/x-data-grid-pro/src/tests/rows.DataGridPro.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -398,12 +398,12 @@ describe('<DataGridPro /> - Rows', () => {
await vi.advanceTimersByTimeAsync(10);
});
expect(getColumnValues(0)).to.deep.equal(['Nike', 'Adidas', 'Puma']);
expect(vi.getTimerCount()).to.equal(3);
expect(vi.getTimerCount()).to.equal(2);

await act(async () => {
await vi.advanceTimersByTimeAsync(100);
});
expect(vi.getTimerCount()).to.equal(1);
expect(vi.getTimerCount()).to.equal(0);
Comment on lines -401 to +406
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I must say I don't understand how useStoreEffect affected this, it doesn't use any timer directly.


// It seems that the trigger is not dependant only on timeout.
vi.useRealTimers();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import * as React from 'react';
import { RefObject } from '@mui/x-internals/types';
import { useStoreEffect } from '@mui/x-internals/store';
import { Size } from '@mui/x-virtualizer/models';
import { GridEventListener } from '../../../models/events';
import { ElementSize } from '../../../models';
import { GridPrivateApiCommunity } from '../../../models/api/gridApiCommunity';
Expand Down Expand Up @@ -137,7 +136,7 @@ export function useGridDimensions(apiRef: RefObject<GridPrivateApiCommunity>, pr
const errorShown = React.useRef(false);

useGridEventPriority(apiRef, 'resize', (size) => {
if (!getRootDimensions().isReady || size === Size.EMPTY) {
if (!getRootDimensions().isReady) {
return;
}
if (size.height === 0 && !errorShown.current && !props.autoHeight && !isJSDOM) {
Expand Down
42 changes: 23 additions & 19 deletions packages/x-virtualizer/src/features/dimensions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import useEventCallback from '@mui/utils/useEventCallback';
import { throttle } from '@mui/x-internals/throttle';
import { isDeepEqual } from '@mui/x-internals/isDeepEqual';
import { roundToDecimalPlaces } from '@mui/x-internals/math';
import { Store, useStore, useStoreEffect, createSelectorMemoized } from '@mui/x-internals/store';
import { Store, useStore, createSelectorMemoized } from '@mui/x-internals/store';
import { ColumnWithWidth, DimensionsState, RowId, RowEntry, RowsMetaState, Size } from '../models';
import type { BaseState, VirtualizerParams } from '../useVirtualizer';

Expand Down Expand Up @@ -119,6 +119,7 @@ function useDimensions(store: Store<BaseState>, params: VirtualizerParams, _api:
topPinnedHeight,
bottomPinnedHeight,
},
onResize,
} = params;

const containerNode = refs.container.current;
Expand Down Expand Up @@ -231,11 +232,13 @@ function useDimensions(store: Store<BaseState>, params: VirtualizerParams, _api:
}

store.update({ dimensions: newDimensions });
onResize?.(newDimensions.root);
}, [
store,
containerNode,
params.dimensions.scrollbarSize,
params.autoHeight,
onResize,
rowHeight,
columnsTotalWidth,
leftPinnedWidth,
Expand All @@ -244,26 +247,16 @@ function useDimensions(store: Store<BaseState>, params: VirtualizerParams, _api:
bottomPinnedHeight,
]);

const { resizeThrottleMs, onResize } = params;
const { resizeThrottleMs } = params;
const updateDimensionCallback = useEventCallback(updateDimensions);
const debouncedUpdateDimensions = React.useMemo(
() =>
resizeThrottleMs > 0
? throttle(() => {
updateDimensionCallback();
onResize?.(store.state.rootSize);
}, resizeThrottleMs)
: undefined,
[resizeThrottleMs, onResize, store, updateDimensionCallback],
() => (resizeThrottleMs > 0 ? throttle(updateDimensionCallback, resizeThrottleMs) : undefined),
[resizeThrottleMs, updateDimensionCallback],
);
React.useEffect(() => debouncedUpdateDimensions?.clear, [debouncedUpdateDimensions]);

useLayoutEffect(() => observeRootNode(containerNode, store), [containerNode, store]);

useLayoutEffect(updateDimensions, [updateDimensions]);

useStoreEffect(store, selectors.rootSize, (_, size) => {
params.onResize?.(size);
const setRootSize = useEventCallback((rootSize: Size) => {
store.state.rootSize = rootSize;

if (isFirstSizing.current || !debouncedUpdateDimensions) {
// We want to initialize the grid dimensions as soon as possible to avoid flickering
Expand All @@ -274,6 +267,13 @@ function useDimensions(store: Store<BaseState>, params: VirtualizerParams, _api:
}
});

useLayoutEffect(
() => observeRootNode(containerNode, store, setRootSize),
[containerNode, store, setRootSize],
);

useLayoutEffect(updateDimensions, [updateDimensions]);

const rowsMeta = useRowsMeta(store, params, updateDimensions);

return {
Expand Down Expand Up @@ -518,7 +518,11 @@ function useRowsMeta(
};
}

function observeRootNode(node: Element | null, store: Store<BaseState>) {
function observeRootNode(
node: Element | null,
store: Store<BaseState>,
setRootSize: (size: Size) => void,
) {
if (!node) {
return undefined;
}
Expand All @@ -528,7 +532,7 @@ function observeRootNode(node: Element | null, store: Store<BaseState>) {
height: roundToDecimalPlaces(bounds.height, 1),
};
if (store.state.rootSize === Size.EMPTY || !Size.equals(initialSize, store.state.rootSize)) {
store.update({ rootSize: initialSize });
setRootSize(initialSize);
}

if (typeof ResizeObserver === 'undefined') {
Expand All @@ -543,7 +547,7 @@ function observeRootNode(node: Element | null, store: Store<BaseState>) {
height: roundToDecimalPlaces(entry.contentRect.height, 1),
};
if (!Size.equals(rootSize, store.state.rootSize)) {
store.update({ rootSize });
setRootSize(rootSize);
}
});

Expand Down
20 changes: 9 additions & 11 deletions packages/x-virtualizer/src/features/virtualization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,23 +176,21 @@ function useVirtualization(store: Store<BaseState>, params: VirtualizerParams, a

const updateRenderContext = React.useCallback(
(nextRenderContext: RenderContext) => {
if (areRenderContextsEqual(nextRenderContext, store.state.virtualization.renderContext)) {
return;
if (!areRenderContextsEqual(nextRenderContext, store.state.virtualization.renderContext)) {
store.set('virtualization', {
...store.state.virtualization,
renderContext: nextRenderContext,
});
}

const didRowsIntervalChange =
nextRenderContext.firstRowIndex !== previousRowContext.current.firstRowIndex ||
nextRenderContext.lastRowIndex !== previousRowContext.current.lastRowIndex;

store.set('virtualization', {
...store.state.virtualization,
renderContext: nextRenderContext,
});

// The lazy-loading hook is listening to `renderedRowsIntervalChange`,
// but only does something if we already have a render context, because
// otherwise we would call an update directly on mount
const isReady = Dimensions.selectors.dimensions(store.state).isReady;
const didRowsIntervalChange =
nextRenderContext.firstRowIndex !== previousRowContext.current.firstRowIndex ||
nextRenderContext.lastRowIndex !== previousRowContext.current.lastRowIndex;

if (isReady && didRowsIntervalChange) {
previousRowContext.current = nextRenderContext;
onRenderContextChange?.(nextRenderContext);
Expand Down