I am trying to manage the index of the current page with state while implementing infinity scroll.
const [pageIndex, setPageIndex = useState<number>(2);
const getList = useCallback(async () => {
try{
// request api
const {data} = await api(pageIndex);
setPageIndex(index => index + 1);
} catch(error) {
// error handling
}
}, [pageIndex]);
const handleObserver = useCallback(
async (
[entry]: IntersectionObserverEntry[],
observer: IntersectionObserver,
) => {
if (entry.isIntersecting) {
observer.unobserve(entry.target);
await getList();
observer.observe(entry.target);
}
},
[getList],
);
useEffect(() => {
if (!loadMoreRef.current) return;
const option = {
root: null,
rootMargin: '0px',
threshold: 0,
};
const observer = new IntersectionObserver(handleObserver, option);
loadMoreRef.current && observer.observe(loadMoreRef.current);
return () => observer && observer.disconnect();
}, [handleObserver]);
I wrote the code as above, but useEffect runs 1 time, 2 times, 3 times, etc., increasing by 1, and the state update is not done properly.
I would appreciate it if you could tell me how to reference and update the latest state value inside intersectionObserver's callback function.
There seems to be a possible issue where updating the pageIndex state triggers all the callbacks to recompute and return new callback references, which eventually retriggers the useEffect callback. This might not be so ideal.
Assuming the useEffect hook and creating intersection observers logic is correct, I suggest using a React ref to cache the pageIndex state value such that its current value can be retrieved at any time in an enclosed callback handler. Remove all the dependencies from the useCallback hook so getList can be a stable reference for the life of the component.
Example:
const [pageIndex, setPageIndex = useState<number>(2);
const pageIndexRef = useRef<number>(pageIndex);
useEffect(() => {
pageIndexRef.current = pageIndex;
}, [pageIndex]);
const getList = useCallback(async () => {
try {
// request api
const { data } = await api(pageIndexRef.current);
setPageIndex(index => index + 1);
} catch(error) {
// error handling
}
}, []);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With