Creating infinitely scrolling SPA using React

Articles app by Arunabh Arjun
Articles App by Arunabh Arjun

Introduction

Short version of this blog

So what is Virtual DOM in React.js

Introduction

Short version of this blog

So what is Virtual DOM in React.js

Why do we need to understand this ?

What happens under the hood in a React.js app

Possible logics that we can use to achieve infinite scrolling

Problem with the 1st solution

Why the 2nd solution is better ?

Also the second approach is the “React.js way” of doing it

What is “ref”, “useRef” & “useCallback” in React.js ?

Implementing infinite scroll

import { useRef, useCallback } from 'react';
const observer = useRef();
const lastComponentRendered = useCallback(
(node) => {
if (loading) return;
if (observer.current) observer.current.disconnect();
observer.current = new IntersectionObserver((entries) => {
if (entries[0].isIntersecting) {
fetchSomeData();
}
});
if (node) observer.current.observe(node);
},
[
loading
]
);
const lastComponentRendered = useCallback(
(node) => {
//do stuff
},
[]
);
const lastComponentRendered = useCallback(
(node) => {
if (loading) return;
//do stuff
},
[]
);
const lastComponentRendered = useCallback(
(node) => {
if (loading) return;
if (observer.current) observer.current.disconnect();
//do stuff
},
[]
);
const lastComponentRendered = useCallback(
(node) => {
if (loading) return;
if (observer.current) observer.current.disconnect();
observer.current = new IntersectionObserver((entries) => {
//do stuff
});
//do stuff
},
[]
);
const lastComponentRendered = useCallback(
(node) => {
if (loading) return;
if (observer.current) observer.current.disconnect();
observer.current = new IntersectionObserver((entries) => {
if (entries[0].isIntersecting) {
//do stuff
}
});
//do stuff
},
[]
);
const lastComponentRendered = useCallback(
(node) => {
if (loading) return;
if (observer.current) observer.current.disconnect();
observer.current = new IntersectionObserver((entries) => {
if (entries[0].isIntersecting) {
fetchSomeData();
}
});
//do stuff
},
[]
);
const lastComponentRendered = useCallback(
(node) => {
if (loading) return;
if (observer.current) observer.current.disconnect();
observer.current = new IntersectionObserver((entries) => {
if (entries[0].isIntersecting) {
fetchSomeData();
}
});
if (node) observer.current.observe(node);
//stuff done
},
[]
);
const lastComponentRendered = useCallback(
(node) => {
if (loading) return;
if (observer.current) observer.current.disconnect();
observer.current = new IntersectionObserver((entries) => {
if (entries[0].isIntersecting) {
fetchSomeData();
}
});
if (node) observer.current.observe(node);
//stuff done
},
[
loading
]
);
return (
<React.Fragment>
<div className='container'>
{fetchedData.map((data, i) => {
if (fetchedData.length === i + 1) {
return (
<div
ref={lastArticle}
key={i}
>
<YourCustomComponent>
{data}
</YourCustomComponent>
</div>
);
}
else
return (
<div
key={i}
>
<YourCustomComponent>
{data}
</YourCustomComponent>
</div>
);

})}
</div>
</React.Fragment>
)

Full code implementation

Bonus : Code snipped to detect bottom of page

/**
* Utility function to listen for scrolling
*/
const handleScroll = () => {
const windowHeight =
'innerHeight' in window
? window.innerHeight
: document.documentElement.offsetHeight;
const body = document.body;
const html = document.documentElement;
const docHeight = Math.max(
body.scrollHeight,
body.offsetHeight,
html.clientHeight,
html.scrollHeight,
html.offsetHeight
);
const windowBottom = windowHeight + window.pageYOffset;
if (windowBottom >= docHeight) {
console.log("Bottom reached!");
}
else {
console.log("Bottom not reached!");
}
};

Conclusion

A product manager and a skilled full-stack developer. Know more @ www.arunabharjun.com

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store