I am having a difficult time trying to set state of a variable during the onScroll event of a custom React functional component. A minimal working CodeSandbox can be seen here: https://codesandbox.io/s/j8ml44
import React, { useEffect, useState, useMemo, useCallback } from "react";
import _ from "lodash";
import ReactDOM from "react-dom";
export function App() {
const [lastScrollTime, setLastScrollTime] = useState(0);
const [nodeFound, setNodeFound] = useState(false);
const ref = useCallback((node) => {
if (node !== null) {
console.log("node found");
handleNodeRender();
}
}, []);
const handleEndScroll = useMemo(
() =>
_.debounce(() => {
console.log("stop");
setLastScrollTime(0);
}, 5000),
[]
);
const handleNodeRender = useMemo(
() =>
_.debounce(() => {
console.log("render");
setNodeFound(true);
}, 100),
[]
);
useEffect(() => {
const handleScroll = () => {
if (lastScrollTime === 0) {
console.log("start");
setLastScrollTime(Date.now());
}
console.log("Scrolling");
handleEndScroll();
};
console.log(document.querySelector("#scroll-0"));
console.log(document.querySelector("#scroll-1"));
if (nodeFound) {
console.log("added listener");
document
.querySelector("#scroll-0")
.addEventListener("scroll", handleScroll);
document
.querySelector("#scroll-1")
.addEventListener("scroll", handleScroll);
}
return () => {
if (nodeFound) {
console.log("removed listener");
document
.querySelector("#scroll-0")
.addEventListener("scroll", handleScroll);
document
.querySelector("#scroll-1")
.removeEventListener("scroll", handleScroll);
}
};
}, [lastScrollTime, nodeFound]);
useEffect(() => {
if (lastScrollTime === 0) {
console.log("5 seconds waited");
}
}, [lastScrollTime]);
const MyList = () => {
return (
<li>
<div>
<hr />
<p>A</p>
<div
ref={ref}
id="scroll-0"
style={{ overflow: "auto", maxHeight: "70px" }}
>
<li>111</li>
<li>222</li>
<li>333</li>
<li>444</li>
<li>555</li>
<li>666</li>
</div>
</div>
</li>
);
};
return (
<div>
<ul>
<MyList />
<li>
<div>
<hr />
<p>B</p>
<div
ref={ref}
id="scroll-1"
style={{ overflow: "auto", maxHeight: "70px" }}
>
<li>111</li>
<li>222</li>
<li>333</li>
<li>444</li>
<li>555</li>
<li>666</li>
</div>
</div>
</li>
</ul>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
When I scroll list B, the console logs and scroll event fires as expected (registers scroll event, logs 'scrolling', and then 5 seconds after scrolling stops, logs 'stop'). However, if I scroll list A, the scrollbox is buggy, to trigger the onScroll's handleEvent I have to attempt to scroll a few times before it will work.
The only difference between list A and B is that list A is extracted into its own functional component. How can I get list A to trigger the onScroll handleEvent event properly? I've tried adding keys, moving the functional component into its own file, but can't get it to work.