Skip to content

Commit 23c3c38

Browse files
committed
fix: should be trigger onVirtualScroll when scrollWidth changed
1 parent 895a64c commit 23c3c38

File tree

2 files changed

+43
-25
lines changed

2 files changed

+43
-25
lines changed

src/List.tsx

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,26 @@
1-
import * as React from 'react';
2-
import { useRef, useState } from 'react';
3-
import { flushSync } from 'react-dom';
41
import classNames from 'classnames';
52
import type { ResizeObserverProps } from 'rc-resize-observer';
63
import ResizeObserver from 'rc-resize-observer';
7-
import Filler from './Filler';
4+
import { useEvent } from 'rc-util';
5+
import useLayoutEffect from 'rc-util/lib/hooks/useLayoutEffect';
6+
import * as React from 'react';
7+
import { useRef, useState } from 'react';
8+
import { flushSync } from 'react-dom';
89
import type { InnerProps } from './Filler';
9-
import type { ScrollBarDirectionType, ScrollBarRef } from './ScrollBar';
10-
import ScrollBar from './ScrollBar';
11-
import type { RenderFunc, SharedConfig, GetKey, ExtraRenderInfo } from './interface';
10+
import Filler from './Filler';
1211
import useChildren from './hooks/useChildren';
13-
import useHeights from './hooks/useHeights';
14-
import useScrollTo from './hooks/useScrollTo';
15-
import type { ScrollPos, ScrollTarget } from './hooks/useScrollTo';
1612
import useDiffItem from './hooks/useDiffItem';
1713
import useFrameWheel from './hooks/useFrameWheel';
14+
import { useGetSize } from './hooks/useGetSize';
15+
import useHeights from './hooks/useHeights';
1816
import useMobileTouchMove from './hooks/useMobileTouchMove';
1917
import useOriginScroll from './hooks/useOriginScroll';
20-
import useLayoutEffect from 'rc-util/lib/hooks/useLayoutEffect';
18+
import type { ScrollPos, ScrollTarget } from './hooks/useScrollTo';
19+
import useScrollTo from './hooks/useScrollTo';
20+
import type { ExtraRenderInfo, GetKey, RenderFunc, SharedConfig } from './interface';
21+
import type { ScrollBarDirectionType, ScrollBarRef } from './ScrollBar';
22+
import ScrollBar from './ScrollBar';
2123
import { getSpinSize } from './utils/scrollbarUtil';
22-
import { useEvent } from 'rc-util';
23-
import { useGetSize } from './hooks/useGetSize';
2424

2525
const EMPTY_DATA = [];
2626

@@ -133,8 +133,14 @@ export function RawList<T>(props: ListProps<T>, ref: React.Ref<ListRef>) {
133133

134134
// ================================= MISC =================================
135135
const useVirtual = !!(virtual !== false && height && itemHeight);
136-
const containerHeight = React.useMemo(() => Object.values(heights.maps).reduce((total, curr) => total + curr, 0), [heights.id, heights.maps]);
137-
const inVirtual = useVirtual && data && (Math.max(itemHeight * data.length, containerHeight) > height || !!scrollWidth);
136+
const containerHeight = React.useMemo(
137+
() => Object.values(heights.maps).reduce((total, curr) => total + curr, 0),
138+
[heights.id, heights.maps],
139+
);
140+
const inVirtual =
141+
useVirtual &&
142+
data &&
143+
(Math.max(itemHeight * data.length, containerHeight) > height || !!scrollWidth);
138144
const isRTL = direction === 'rtl';
139145

140146
const mergedClassName = classNames(prefixCls, { [`${prefixCls}-rtl`]: isRTL }, className);
@@ -312,9 +318,9 @@ export function RawList<T>(props: ListProps<T>, ref: React.Ref<ListRef>) {
312318

313319
const lastVirtualScrollInfoRef = useRef(getVirtualScrollInfo());
314320

315-
const triggerScroll = useEvent(() => {
321+
const triggerScroll = useEvent((params?: { x?: number; y?: number }) => {
316322
if (onVirtualScroll) {
317-
const nextInfo = getVirtualScrollInfo();
323+
const nextInfo = { ...getVirtualScrollInfo(), ...params };
318324

319325
// Trigger when offset changed
320326
if (
@@ -425,9 +431,9 @@ export function RawList<T>(props: ListProps<T>, ref: React.Ref<ListRef>) {
425431
// Sync scroll left
426432
useLayoutEffect(() => {
427433
if (scrollWidth) {
428-
setOffsetLeft((left) => {
429-
return keepInHorizontalRange(left);
430-
});
434+
const newOffsetLeft = keepInHorizontalRange(offsetLeft);
435+
setOffsetLeft(newOffsetLeft);
436+
triggerScroll({ x: newOffsetLeft });
431437
}
432438
}, [size.width, scrollWidth]);
433439

tests/scrollWidth.test.tsx

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import React from 'react';
1+
import '@testing-library/jest-dom';
22
import { act, fireEvent, render } from '@testing-library/react';
3+
import { _rs as onLibResize } from 'rc-resize-observer/lib/utils/observerUtil';
34
import { spyElementPrototypes } from 'rc-util/lib/test/domHook';
5+
import React from 'react';
46
import type { ListRef } from '../src';
57
import List, { type ListProps } from '../src';
6-
import { _rs as onLibResize } from 'rc-resize-observer/lib/utils/observerUtil';
7-
import '@testing-library/jest-dom';
88

99
const ITEM_HEIGHT = 20;
1010

@@ -91,14 +91,16 @@ describe('List.scrollWidth', () => {
9191
const onVirtualScroll = jest.fn();
9292
const listRef = React.createRef<ListRef>();
9393

94-
const { container } = await genList({
94+
const props = {
9595
itemHeight: ITEM_HEIGHT,
9696
height: 100,
9797
data: genData(100),
9898
scrollWidth: 1000,
9999
onVirtualScroll,
100100
ref: listRef,
101-
});
101+
};
102+
103+
const { container, rerender } = await genList(props);
102104

103105
await act(async () => {
104106
onLibResize([
@@ -134,6 +136,16 @@ describe('List.scrollWidth', () => {
134136

135137
expect(onVirtualScroll).toHaveBeenCalledWith({ x: 900, y: 0 });
136138
expect(listRef.current.getScrollInfo()).toEqual({ x: 900, y: 0 });
139+
140+
act(() => {
141+
rerender(
142+
<List component="ul" itemKey="id" {...props} scrollWidth={600}>
143+
{({ id }) => <li>{id}</li>}
144+
</List>,
145+
);
146+
});
147+
expect(onVirtualScroll).toHaveBeenCalledWith({ x: 500, y: 0 });
148+
expect(listRef.current.getScrollInfo()).toEqual({ x: 500, y: 0 });
137149
});
138150

139151
it('wheel', async () => {

0 commit comments

Comments
 (0)