Skip to content

Commit

Permalink
fix: calculate range when outer size is defined and count > 0 (#603)
Browse files Browse the repository at this point in the history
  • Loading branch information
piecyk committed Oct 8, 2023
1 parent 1efbfb0 commit 8c3e23d
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 25 deletions.
17 changes: 17 additions & 0 deletions packages/react-virtual/__tests__/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,18 +41,27 @@ function List({

const parentRef = React.useRef<HTMLDivElement>(null)

const elementRectCallbackRef = React.useRef<
((rect: { height: number; width: number }) => void) | null
>(null)

const rowVirtualizer = useVirtualizer({
count,
getScrollElement: () => parentRef.current,
estimateSize: () => 50,
overscan,
observeElementRect: (_, cb) => {
cb({ height, width })
elementRectCallbackRef.current = cb
},
measureElement: () => itemSize ?? 0,
rangeExtractor,
})

React.useEffect(() => {
elementRectCallbackRef.current?.({ height, width })
}, [height, width])

const measureElement = dynamic ? rowVirtualizer.measureElement : undefined

const items = rowVirtualizer.getVirtualItems()
Expand Down Expand Up @@ -172,3 +181,11 @@ test('should handle count change', () => {
expect(screen.queryByText('Row 4')).toBeInTheDocument()
expect(screen.queryByText('Row 5')).not.toBeInTheDocument()
})

test('should handle handle height change', () => {
const { rerender } = render(<List count={0} height={0} />)

expect(screen.queryByText('Row 0')).not.toBeInTheDocument()
rerender(<List count={1} height={200} />)
expect(screen.queryByText('Row 0')).toBeInTheDocument()
})
2 changes: 1 addition & 1 deletion packages/virtual-core/__tests__/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ test('should export the Virtualizer class', () => {
expect(Virtualizer).toBeDefined()
})

test('shoul', () => {
test('should return empty items for empty scroll element', () => {
const virtualizer = new Virtualizer({
count: 100,
getScrollElement: () => null,
Expand Down
44 changes: 20 additions & 24 deletions packages/virtual-core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -307,10 +307,7 @@ export class Virtualizer<
unobserve: (target: Element) => get()?.unobserve(target),
}
})()
range: { startIndex: number; endIndex: number } = {
startIndex: 0,
endIndex: 0,
}
range: { startIndex: number; endIndex: number } | null = null

constructor(opts: VirtualizerOptions<TScrollElement, TItemElement>) {
this.setOptions(opts)
Expand Down Expand Up @@ -385,15 +382,8 @@ export class Virtualizer<

this.unsubs.push(
this.options.observeElementRect(this, (rect) => {
const prev = this.scrollRect
this.scrollRect = rect
if (
this.options.horizontal
? rect.width !== prev.width
: rect.height !== prev.height
) {
this.maybeNotify()
}
this.maybeNotify()
}),
)

Expand Down Expand Up @@ -549,11 +539,14 @@ export class Virtualizer<
calculateRange = memo(
() => [this.getMeasurements(), this.getSize(), this.scrollOffset],
(measurements, outerSize, scrollOffset) => {
return (this.range = calculateRange({
measurements,
outerSize,
scrollOffset,
}))
return (this.range =
measurements.length > 0 && outerSize > 0
? calculateRange({
measurements,
outerSize,
scrollOffset,
})
: null)
},
{
key: process.env.NODE_ENV !== 'production' && 'calculateRange',
Expand All @@ -563,9 +556,13 @@ export class Virtualizer<

private maybeNotify = memo(
() => {
const range = this.calculateRange()
this.calculateRange()

return [range.startIndex, range.endIndex, this.isScrolling]
return [
this.range ? this.range.startIndex : null,
this.range ? this.range.endIndex : null,
this.isScrolling,
]
},
() => {
this.notify()
Expand All @@ -574,8 +571,8 @@ export class Virtualizer<
key: process.env.NODE_ENV !== 'production' && 'maybeNotify',
debug: () => this.options.debug,
initialDeps: [
this.range.startIndex,
this.range.endIndex,
this.range ? this.range.startIndex : null,
this.range ? this.range.endIndex : null,
this.isScrolling,
],
},
Expand All @@ -587,10 +584,9 @@ export class Virtualizer<
this.calculateRange(),
this.options.overscan,
this.options.count,
this.getSize(),
],
(rangeExtractor, range, overscan, count, outerSize) => {
return outerSize === 0
(rangeExtractor, range, overscan, count) => {
return range === null
? []
: rangeExtractor({
...range,
Expand Down

0 comments on commit 8c3e23d

Please sign in to comment.