Skip to content

Commit 62fe41e

Browse files
authored
fix: Item render will also collect heights (#58)
* fix: Item render will also collect heights * update test case
1 parent c3d8543 commit 62fe41e

File tree

3 files changed

+36
-20
lines changed

3 files changed

+36
-20
lines changed

src/Filler.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ const Filler: React.FC<FillerProps> = ({
4848
<div style={outerStyle}>
4949
<ResizeObserver
5050
onResize={({ offsetHeight }) => {
51-
if (offsetHeight) {
51+
if (offsetHeight && onInnerResize) {
5252
onInnerResize();
5353
}
5454
}}

src/hooks/useHeights.tsx

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,41 @@ export default function useHeights<T>(
1414
const [updatedMark, setUpdatedMark] = React.useState(0);
1515
const instanceRef = useRef(new Map<React.Key, HTMLElement>());
1616
const heightsRef = useRef(new CacheMap());
17+
const heightUpdateIdRef = useRef(0);
18+
19+
function collectHeight() {
20+
heightUpdateIdRef.current += 1;
21+
const currentId = heightUpdateIdRef.current;
22+
23+
Promise.resolve().then(() => {
24+
// Only collect when it's latest call
25+
if (currentId !== heightUpdateIdRef.current) return;
26+
27+
let changed = false;
28+
29+
instanceRef.current.forEach((element, key) => {
30+
if (element && element.offsetParent) {
31+
const htmlElement = findDOMNode<HTMLElement>(element);
32+
const { offsetHeight } = htmlElement;
33+
if (heightsRef.current.get(key) !== offsetHeight) {
34+
changed = true;
35+
heightsRef.current.set(key, htmlElement.offsetHeight);
36+
}
37+
}
38+
});
39+
if (changed) {
40+
setUpdatedMark(c => c + 1);
41+
}
42+
});
43+
}
1744

1845
function setInstanceRef(item: T, instance: HTMLElement) {
1946
const key = getKey(item);
2047
const origin = instanceRef.current.get(key);
2148

2249
if (instance) {
2350
instanceRef.current.set(key, instance);
51+
collectHeight();
2452
} else {
2553
instanceRef.current.delete(key);
2654
}
@@ -35,23 +63,5 @@ export default function useHeights<T>(
3563
}
3664
}
3765

38-
function collectHeight() {
39-
let changed = false;
40-
41-
instanceRef.current.forEach((element, key) => {
42-
if (element && element.offsetParent) {
43-
const htmlElement = findDOMNode<HTMLElement>(element);
44-
const { offsetHeight } = htmlElement;
45-
if (heightsRef.current.get(key) !== offsetHeight) {
46-
changed = true;
47-
heightsRef.current.set(key, htmlElement.offsetHeight);
48-
}
49-
}
50-
});
51-
if (changed) {
52-
setUpdatedMark(c => c + 1);
53-
}
54-
}
55-
5666
return [setInstanceRef, collectHeight, heightsRef.current, updatedMark];
5767
}

tests/list.test.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React from 'react';
22
import { mount } from 'enzyme';
3+
import { act } from 'react-dom/test-utils';
34
import List from '../src';
45
import Filler from '../src/Filler';
56
import { spyElementPrototypes } from './utils/domHook';
@@ -188,7 +189,7 @@ describe('List.Basic', () => {
188189
mockElement.mockRestore();
189190
});
190191

191-
it('work', () => {
192+
it('work', async () => {
192193
const wrapper = genList({ itemHeight: 20, height: 40, data: genData(3) });
193194
wrapper
194195
.find('Filler')
@@ -197,6 +198,11 @@ describe('List.Basic', () => {
197198
.onResize({ offsetHeight: 0 });
198199
expect(collected).toBeFalsy();
199200

201+
// Wait for collection
202+
await act(async () => {
203+
await Promise.resolve();
204+
});
205+
200206
wrapper
201207
.find('Filler')
202208
.find('ResizeObserver')

0 commit comments

Comments
 (0)