I'm currently practicing infinite scrolling using a cross-observer with typescript.
After this question is resolved, variable types in typescript will be carefully set again, now my important question is:
I wonder why the code inside the useEffect() hook is executed twice at the same time when target and root intersect. And I'm also curious about the solution.
I'm also wondering if it's desirable to put that code inside a useEffect.
I want to get one additional data at the moment the target and root intersect. But the current situation is that the code inside is executed twice, and the data is fetched twice.
Also, if you put a data
variable in the dependency array, the number of executions at a time will grow wildly and irregularly.
//PracticePage.tsx
import styled from "styled-components";
import { useEffect, useRef, useState } from "react";
const PracticePage = () => {
const [add, setAdd] = useState([1]);
const [data, setData] = useState([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
const targetRef = useRef<HTMLDivElement>(null);
const testFetch = (delay = 1000) =>
new Promise((res) => setTimeout(res, delay));
let observerObj;
useEffect(() => {
observerObj = new IntersectionObserver(
async ([entry], observer) => {
if (entry.isIntersecting) {
await testFetch();
console.log("intersect!"); // run twice at the same time
setData((prev) => prev.concat(add));
// io.unobserve(targetRef.current!);
}
},
{
root: null,
rootMargin: "0px 0px 0px 0px",
threshold: 0,
}
);
observerObj.observe(targetRef.current!);
}, []);
return (
<>
<Container>
{data.map((d, index) => (
<Items key={index}>{d}</Items>
))}
<Target ref={targetRef}>target</Target>
</Container>
</>
);
};
const Container = styled.div`
width: 100vw;
height: 500px;
background-color: gray;
overflow-y: scroll;
`;
const Items = styled.div`
width: 50vw;
height: 50px;
margin: 10px auto;
background-color: yellow;
`;
const Target = styled.div`
width: 50vw;
height: 50px;
margin: 10px auto;
color: white;
background-color: black;
`;
export default PracticePage;