In this post, we going to use the useIntersectionObserver
hook that I create in
Article No Longer Available
In short, this hook will check if the target element is in the viewport of a document or window.
Ok, let's start with a component that will load a picture:
function Component({ id }: { id: number }) {
const [data, setData] = useState<any>({});
useEffect(() => {
fetch(`https://jsonplaceholder.typicode.com/photos/${id}`)
.then((res) => res.json())
.then((data) => {
setData(data);
});
}, []);
return (
<div style={{ height: "600px" }}>
<img src={data.url} alt="pic" />
</div>
);
}
then, we can use it inside the App.js:
const pageSize=5;
export default function App() {
const [count, setCount] = useState(0);
return (
<div className="App">
{(() => {
const children = [];
for (let i = 1; i <= count * pageSize; i++) {
children.push(<Component key={i} id={i} />);
}
return children;
})()}
</div>
);
}
Now, we add the hook, a component that can be used as trigger, and an useEffect that can increase the counter:
const pageSize = 5;
export default function App() {
const [count, setCount] = useState(0);
const ref = useRef(null);
const isBottomVisible = useIntersectionObserver(
ref,
{
threshold: 0 //trigger event as soon as the element is in the viewport.
},
false // don't remove the observer after intersected.
);
useEffect(() => {
//load next page when bottom is visible
isBottomVisible && setCount(count + 1);
}, [isBottomVisible]);
return (
<div className="App">
{(() => {
const children = [];
for (let i = 1; i <= count * pageSize; i++) {
children.push(<Component key={i} id={i} />);
}
return children;
})()}
<div ref={ref} style={{ width: "100%", height: "20px" }}>
Bottom
</div>
</div>
);
}
Now we can test the code, here is a demo:
Thank you all!
Top comments (2)
Nice
Exactly what I was looking for
Thanks!!!! This is the easiest answer I was looking for!!!