Skip to content

Commit

Permalink
fix: Item render will also collect heights (#58)
Browse files Browse the repository at this point in the history
* fix: Item render will also collect heights

* update test case
  • Loading branch information
zombieJ authored Sep 9, 2020
1 parent c3d8543 commit 62fe41e
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 20 deletions.
2 changes: 1 addition & 1 deletion src/Filler.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ const Filler: React.FC<FillerProps> = ({
<div style={outerStyle}>
<ResizeObserver
onResize={({ offsetHeight }) => {
if (offsetHeight) {
if (offsetHeight && onInnerResize) {
onInnerResize();
}
}}
Expand Down
46 changes: 28 additions & 18 deletions src/hooks/useHeights.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,41 @@ export default function useHeights<T>(
const [updatedMark, setUpdatedMark] = React.useState(0);
const instanceRef = useRef(new Map<React.Key, HTMLElement>());
const heightsRef = useRef(new CacheMap());
const heightUpdateIdRef = useRef(0);

function collectHeight() {
heightUpdateIdRef.current += 1;
const currentId = heightUpdateIdRef.current;

Promise.resolve().then(() => {
// Only collect when it's latest call
if (currentId !== heightUpdateIdRef.current) return;

let changed = false;

instanceRef.current.forEach((element, key) => {
if (element && element.offsetParent) {
const htmlElement = findDOMNode<HTMLElement>(element);
const { offsetHeight } = htmlElement;
if (heightsRef.current.get(key) !== offsetHeight) {
changed = true;
heightsRef.current.set(key, htmlElement.offsetHeight);
}
}
});
if (changed) {
setUpdatedMark(c => c + 1);
}
});
}

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

if (instance) {
instanceRef.current.set(key, instance);
collectHeight();
} else {
instanceRef.current.delete(key);
}
Expand All @@ -35,23 +63,5 @@ export default function useHeights<T>(
}
}

function collectHeight() {
let changed = false;

instanceRef.current.forEach((element, key) => {
if (element && element.offsetParent) {
const htmlElement = findDOMNode<HTMLElement>(element);
const { offsetHeight } = htmlElement;
if (heightsRef.current.get(key) !== offsetHeight) {
changed = true;
heightsRef.current.set(key, htmlElement.offsetHeight);
}
}
});
if (changed) {
setUpdatedMark(c => c + 1);
}
}

return [setInstanceRef, collectHeight, heightsRef.current, updatedMark];
}
8 changes: 7 additions & 1 deletion tests/list.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from 'react';
import { mount } from 'enzyme';
import { act } from 'react-dom/test-utils';
import List from '../src';
import Filler from '../src/Filler';
import { spyElementPrototypes } from './utils/domHook';
Expand Down Expand Up @@ -188,7 +189,7 @@ describe('List.Basic', () => {
mockElement.mockRestore();
});

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

// Wait for collection
await act(async () => {
await Promise.resolve();
});

wrapper
.find('Filler')
.find('ResizeObserver')
Expand Down

1 comment on commit 62fe41e

@vercel
Copy link

@vercel vercel bot commented on 62fe41e Sep 9, 2020

Choose a reason for hiding this comment

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

Please sign in to comment.