Skip to content

Commit

Permalink
Merge pull request #154 from wellyshen/fix/on-scroll-events
Browse files Browse the repository at this point in the history
Fix(useVirtual): do not trigger `onScroll` and `loadMore` by internally scroll-to method
  • Loading branch information
wellyshen committed Jun 19, 2021
2 parents f48daae + abc5880 commit 0eeae8f
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 21 deletions.
5 changes: 5 additions & 0 deletions .changeset/gorgeous-avocados-develop.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"react-cool-virtual": patch
---

fix(useVirtual): do not trigger `onScroll` and `loadMore` by internally scroll-to method
21 changes: 10 additions & 11 deletions app/src/App/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -114,16 +114,17 @@ const getMockData = (count: number, min = 25) =>
size: min + Math.round(Math.random() * 150),
}));

const mockData = getMockData(50);
const mockData = getMockData(100);

export default (): JSX.Element => {
const [itemCount, setItemCount] = useState(mockData.length);
const { outerRef, innerRef, items } = useVirtual<
const { outerRef, innerRef, items, scrollTo } = useVirtual<
HTMLDivElement,
HTMLDivElement
>({
itemCount,
// resetScroll: true,
resetScroll: true,
onScroll: (e) => console.log("LOG ===> ", e),
});

return (
Expand All @@ -134,25 +135,23 @@ export default (): JSX.Element => {
<div
key={index}
className={`${styles.item} ${index % 2 ? styles.dark : ""}`}
style={{
position: "absolute",
top: start,
height: `${size}px`,
width: "100%",
}}
style={{ height: `${size}px` }}
>
{index}
</div>
))}
</div>
</div>
<button type="button" onClick={() => scrollTo(100)}>
Scroll To...
</button>
<button
type="button"
onClick={() =>
setItemCount((prevCount) => (prevCount === 50 ? 25 : 50))
setItemCount((prevCount) => (prevCount === 50 ? 100 : 50))
}
>
Change
Change Item Count
</button>
</div>
);
Expand Down
27 changes: 17 additions & 10 deletions src/useVirtual.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ export default <
getInitItems(itemSize, ssrItemCount)
);
const isMountedRef = useRef(false);
const isScrollingRef = useRef(true);
const isScrollToItemRef = useRef(false);
const hasDynamicSizeRef = useRef(false);
const rosRef = useRef<Map<Element, ResizeObserver>>(new Map());
Expand Down Expand Up @@ -176,8 +177,11 @@ export default <
);

const scrollTo = useCallback(
(offset: number) => {
if (outerRef.current) outerRef.current[scrollKey] = offset;
(offset: number, isScrolling = true) => {
if (outerRef.current) {
isScrollingRef.current = isScrolling;
outerRef.current[scrollKey] = offset;
}
},
[scrollKey]
);
Expand Down Expand Up @@ -363,7 +367,7 @@ export default <
if (measuredSize !== size || start !== prevEnd) {
// To prevent dynamic size from jumping during backward scrolling
if (i < prevItemIdxRef.current && start < scrollOffset)
scrollTo(scrollOffset + measuredSize - size);
scrollTo(scrollOffset + measuredSize - size, false);

msDataRef.current[i] = getMeasure(i, measuredSize);
if (!isScrollToItemRef.current)
Expand Down Expand Up @@ -480,19 +484,21 @@ export default <
measureItems(hasDynamicSizeRef.current);
handleScroll(scrollOffsetRef.current);

if (resetScroll && itemCount !== prevItemCount) scrollTo(0);
if (resetScroll && itemCount !== prevItemCount) scrollTo(0, false);

if (!isMountedRef.current) {
isMountedRef.current = true;
return;
}

if (!hasDynamicSizeRef.current && !isSameWidth) {
const totalSize = msDataRef.current[msDataRef.current.length - 1]?.end;
const ratio = totalSize / prevTotalSize || 1;

scrollTo(scrollOffsetRef.current * ratio);
scrollTo(scrollOffsetRef.current * ratio, false);
}

if (isMountedRef.current && !isSameSize && onResizeRef.current)
onResizeRef.current(rect);

isMountedRef.current = true;
if (!isSameSize && onResizeRef.current) onResizeRef.current(rect);
},
[itemCount, resetScroll, handleScroll, measureItems, onResizeRef, scrollTo]
);
Expand All @@ -513,7 +519,8 @@ export default <
? uxScrolling(Math.abs(scrollOffset - scrollOffsetRef.current))
: uxScrolling;

handleScroll(scrollOffset, true, uxScrolling);
handleScroll(scrollOffset, isScrollingRef.current, uxScrolling);
isScrollingRef.current = true;
scrollOffsetRef.current = scrollOffset;
};

Expand Down

0 comments on commit 0eeae8f

Please sign in to comment.