DEV Community

Cover image for InfinityScroll - Just like TikTok!
Jorjis Hasan
Jorjis Hasan

Posted on • Updated on

InfinityScroll - Just like TikTok!

๐Ÿ“บ preview.jpg
Watch it โœจ Live โœจ
Live Preview
๐Ÿ“ infinityscroll.js
Don't dwell on the pain. Just take a quick look. After reading the article, everything will become clear to you. ๐Ÿ“ SOURCE CODE


import { useState, useEffect } from "react";
import ReactDOM from "react-dom/client";

function App() {
  const [numArr, setNumArr] = useState(Array.from({ length: 20 }, (_, i) => i));

  const handleScroll = () => {
    if (window.innerHeight + window.scrollY >= document.body.offsetHeight) {
      setNumArr((prevNums) => [
        ...prevNums,
        ...Array.from({ length: 20 }, (_, i) => i + prevNums.length),
      ]);
    }
  };

  // Listen for scroll events
  useEffect(() => {
    window.addEventListener("scroll", handleScroll);
    return () => window.removeEventListener("scroll", handleScroll);
  }, []);

  return (
    <div className="font-serif text-3xl text-center">
      {numArr.map((num, index) => (
        <div
          key={index}
          className="m-2 p-5 bg-white shadow-md rounded cursor-pointer"
        >
          {num}
        </div>
      ))}
    </div>
  );
}


const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<App />);


Enter fullscreen mode Exit fullscreen mode

I promise! Following my steps, you can natively implement Infinity Scrolling. This means you don't have to worry about installing extra packages or adding unnecessary weight to your app.

  1. Initial Render
  2. Event Listening
  3. Event Handling

Don't be afraid of these jargon words ๐Ÿ˜„. I'm holding your hands ๐Ÿ’ช. Once you reach the end of the article, it'll make you proud.


STEP 1: โค Initial Render ๐Ÿ“ƒ
Initially, let's load/fill the page with 20 elements.

CODE:



function App() {
  const [numArr, setNumArr] = useState(Array.from({ length: 20 }, (_, i) => i));

  return (
    <div className="font-serif text-3xl text-center">
      {numArr.map((num, index) => (
        <div
          key={index}
          className="m-2 p-5 bg-white shadow-md rounded cursor-pointer"
        >
          {num}
        </div>
      ))}
    </div>
  );



Enter fullscreen mode Exit fullscreen mode

Explain: Create a numArr state variable on top of the App component with values 0 through 20. Over the return statement, render items of numArr as elements. STEP 1 is done.


STEP 2: โค Event Listening ๐Ÿ‘‚
Browsers offer us bunch of events: Mouse(click, mousemove, mouseover), Keybaord Event(keydown, keypress, keyup), and Window Event(scroll, resize, load).

Since we are implementing a feature based on scrolling, we need to keep track of scroll activity. To get notified, we'll set a watcher inside the App() component that continuously checks whether a scroll happens.

CODE:



function App() {
// Listen for scroll events
   useEffect(() => {
    window.addEventListener("scroll", handleScroll);
    return () => window.removeEventListener("scroll", handleScroll);
  }, []);
}


Enter fullscreen mode Exit fullscreen mode

Explain: We set the watcher or event-listener, that event listener window.addEventListener("scroll", handleScroll) takes 2 arguments: the event name scroll and a callback-function handleScroll that defines what to do when the event is triggered. Step 2 is done. The return statement does cleanup. You can skip it for now with this setup.


STEP-3: โค Event Handling ๐Ÿ’ช
Assuming that scrolling happens, the contract of the handleScroll function would be to load more data when the user reaches the end of the page.

CODE:



  //This function will invoked when event triggered
  const handleScroll = () => {
    if (window.innerHeight + window.scrollY >= document.body.offsetHeight) {
      setNumArr((prevNums) => [
        ...prevNums,
        ...Array.from({ length: 20 }, (_, i) => i + prevNums.length),
      ]);
    }
  };



Enter fullscreen mode Exit fullscreen mode

Explain: The if statement verifies that the user has reached the end of the page. The code inside the if block accumulates 15 new data to the numArr variable. Since numArr is a state variable, it will re-render the state after every update. It's react's native state behavior.

Yay ๐Ÿ˜€! You have done the last step. You have achieved more optimized infinity scrolling.

NB: I used numbers as placeholders. In a real scenario, you'll fetch data across pages via API.

Top comments (0)