Skip to content

Commit 95247f7

Browse files
author
ecorreia
committed
Merge branch 'fixes' into release-1.4.2
2 parents 0b97b86 + ef2e6b3 commit 95247f7

File tree

3 files changed

+61
-72
lines changed

3 files changed

+61
-72
lines changed

src/___subComponents/ScrollRenderer.tsx

Lines changed: 46 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import {any, arrayOf, element, func, node, oneOfType} from 'prop-types';
2-
import React, {createRef, useEffect, useLayoutEffect, useState, Ref} from 'react';
3-
import convertListToArray from '../___utils/convertListToArray';
2+
import React, {createRef, Ref, useEffect, useLayoutEffect, useState} from 'react';
43
import {handleRenderGroupSeparator, handleRenderItem, renderFunc} from './uiFunctions';
54

65
interface Props {
@@ -11,82 +10,84 @@ interface Props {
1110

1211
const ScrollRenderer = (props: Props) => {
1312
const {list, renderItem, groupSeparator} = props;
14-
const [render, setRender] = useState({renderList: [], index: 0, prevScrollPosition: 0});
13+
const [render, setRender] = useState({renderList: [], index: 0});
1514
const [mounted, setMounted] = useState(false);
16-
const dataList = convertListToArray(list);
15+
const [setupCount, setSetupCount] = useState(-1);
1716
const containerRef: Ref<HTMLElement> = createRef();
18-
let adding = false;
1917

2018
const renderThisItem = handleRenderItem(renderItem, handleRenderGroupSeparator(groupSeparator));
2119

22-
const addItem = (container: any, prevScrollPosition = render.prevScrollPosition) => {
23-
if (!adding && render.index < dataList.length) {
24-
adding = true;
25-
// @ts-ignore
26-
const count = getComputedStyle(container as HTMLElement).display === 'grid' ? 10 : 5;
20+
const updateRenderInfo = (count = 10) => {
21+
if (render.index < list.length) {
22+
const index = render.index + count;
2723
setRender({
28-
prevScrollPosition,
29-
renderList: [...render.renderList, ...dataList.slice(render.index, render.index + count)] as any,
30-
index: render.index + count
24+
renderList: list.slice(0, index) as any,
25+
index
3126
});
3227
}
3328
};
3429

3530
const onScroll = (span: any) => () => {
36-
const startingPoint = span.parentNode.offsetTop + span.parentNode.offsetHeight;
37-
const anchorPos = span.offsetTop - span.parentNode.scrollTop;
31+
requestAnimationFrame(() => {
32+
const startingPoint = span.parentNode.offsetTop + span.parentNode.offsetHeight;
33+
const anchorPos = span.offsetTop - span.parentNode.scrollTop;
3834

39-
if (anchorPos <= (startingPoint + (span.parentNode.offsetHeight * 2))) {
40-
requestAnimationFrame(() => addItem(span.parentNode, span.parentNode.scrollTop));
41-
}
35+
if (anchorPos <= (startingPoint + (span.parentNode.offsetHeight * 2))) {
36+
updateRenderInfo();
37+
}
38+
});
4239
};
4340

44-
useEffect(() => {
45-
if (mounted) { // reset list on list change
46-
setRender({
47-
renderList: [],
48-
index: 0,
49-
prevScrollPosition: 0
50-
});
51-
}
52-
}, [list]);
53-
5441
useEffect(() => { // when mounted
5542
setMounted(true);
5643

5744
return () => { // when unmounted
58-
if (containerRef.current) {
59-
(containerRef as any).current.parentNode.removeEventListener('scroll', onScroll, true);
60-
}
45+
setMounted(false);
6146
};
6247
}, []);
6348

49+
useLayoutEffect(() => {
50+
if (mounted) { // reset list on list change
51+
const span: any = containerRef.current;
52+
const pos = span.parentNode.scrollTop;
53+
const index = Math.max(render.renderList.length, setupCount);
54+
55+
setRender({
56+
renderList: list.slice(0, index) as any,
57+
index
58+
});
59+
60+
requestAnimationFrame(() => {
61+
span.parentNode.scrollTop = pos;
62+
});
63+
}
64+
}, [list]);
65+
6466
useLayoutEffect(() => {
6567
const span: any = containerRef.current;
66-
let container: any = null;
6768
const handleScroll = onScroll(span);
69+
let container: any = null;
70+
6871
if (span) {
6972
container = span.parentNode;
70-
// populate double the container height of items
71-
if (render.index === 0 || container.scrollHeight <= (container.offsetHeight * 2)) {
72-
requestAnimationFrame(() => addItem(container));
73-
}
74-
75-
if (render.index > 0 && dataList.length === render.renderList.length) {
76-
container.removeEventListener('scroll', handleScroll, true);
77-
} else {
78-
container.addEventListener('scroll', handleScroll, true);
79-
}
73+
requestAnimationFrame(() => {
74+
// populate double the container height of items
75+
if (render.index === 0 || container.scrollHeight <= (container.offsetHeight * 2)) {
76+
updateRenderInfo();
77+
} else if (setupCount === -1) {
78+
setSetupCount(render.index);
79+
}
80+
});
8081

81-
adding = false;
82+
container.addEventListener('scroll', handleScroll, {passive: true});
8283
}
8384

8485
return () => { // when unmounted
8586
if (span) {
86-
container.removeEventListener('scroll', handleScroll, true);
87+
container.removeEventListener('scroll', handleScroll, {passive: true});
8788
}
8889
};
89-
}, [render.index]);
90+
}, [render.index, list.length]);
9091

9192
return (
9293
<>

tests/FlatList.test.tsx

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -154,30 +154,33 @@ describe('FlatList', () => {
154154

155155
const {asFragment, getAllByText} = render(
156156
<FlatList
157-
list={list}
157+
list={[...list, ...list]}
158158
renderItem={renderItem}
159159
renderOnScroll
160160
/>,
161161
{container}
162162
);
163163

164164
// initial render
165-
console.log('-- container', container.outerHTML);
166165
let items = getAllByText(/age-.*/);
167166

168167
expect(asFragment()).toMatchSnapshot();
169-
expect(items.length).toBe(5);
170-
expect(items.map(i => i.textContent)).toEqual(['age-1', 'age-3', 'age-45', 'age-8', 'age-0']);
168+
expect(items.length).toBe(10);
169+
expect(items.map(i => i.textContent)).toEqual([
170+
'age-1', 'age-3', 'age-45', 'age-8', 'age-0', 'age-20', 'age-10', 'age-1', 'age-3', 'age-45'
171+
]);
171172

172173
// scroll render
173174
fireEvent.scroll(container, {target: {scrollTop: 150}});
174175

175176
items = getAllByText(/age-.*/);
176177

177178
expect(container.scrollTop).toBe(150);
178-
expect(asFragment()).toMatchSnapshot();
179-
expect(items.length).toBe(7);
180-
expect(items.map(i => i.textContent)).toEqual(['age-1', 'age-3', 'age-45', 'age-8', 'age-0', 'age-20', 'age-10']);
179+
expect(items.length).toBe(14);
180+
expect(items.map(i => i.textContent)).toEqual([
181+
'age-1', 'age-3', 'age-45', 'age-8', 'age-0', 'age-20', 'age-10',
182+
'age-1', 'age-3', 'age-45', 'age-8', 'age-0', 'age-20', 'age-10'
183+
]);
181184
raf.mockClear();
182185
});
183186
});

tests/__snapshots__/FlatList.test.tsx.snap

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -459,35 +459,20 @@ exports[`FlatList Should render on scroll 1`] = `
459459
<li>
460460
age-0
461461
</li>
462-
<span
463-
class="___scroll-renderer-anchor"
464-
style="visibility: hidden; height: 1px;"
465-
/>
466-
</DocumentFragment>
467-
`;
468-
469-
exports[`FlatList Should render on scroll 2`] = `
470-
<DocumentFragment>
471-
<li>
472-
age-1
473-
</li>
474-
<li>
475-
age-3
476-
</li>
477462
<li>
478-
age-45
463+
age-20
479464
</li>
480465
<li>
481-
age-8
466+
age-10
482467
</li>
483468
<li>
484-
age-0
469+
age-1
485470
</li>
486471
<li>
487-
age-20
472+
age-3
488473
</li>
489474
<li>
490-
age-10
475+
age-45
491476
</li>
492477
<span
493478
class="___scroll-renderer-anchor"

0 commit comments

Comments
 (0)