Maximize User Experience with Infinite Scroll

Tapajyoti Bose - Mar 21 '21 - - Dev Community

What is Infinite Scroll?

Infinite Scrolling is highly trending as an interaction behavior on pages and lists. The basic functionality is that, as the user scrolls through content, more content is loaded automatically. With the popularity of social media, massive amounts of data are being consumed, Infinite Scrolling offers an efficient way to browse that ocean of information, without having to wait for pages to preload. Rather, the user enjoys a truly responsive experience, whatever device they’re using.

Demo

Getting Started

We will be implementing Infinite Scroll in a React Project. Set up a React Project before continuing.

Implementing Infinite Scroll

First let's add the Item component.

const Item = ({ children, reference }) => {
  return (
    <div ref={reference}>
      {children}
    </div>
  );
};
Enter fullscreen mode Exit fullscreen mode

We need to use ref to store the reference to the last element for Infinite Scroll.

Creating the App component.

const MAX_PAGES = 5;

const App = () => {
  const [items, setItems] = React.useState([]);
  const [isLoading, setIsLoading] = React.useState(false);
  const [hasMore, setHasMore] = React.useState(true);
  const [pages, setPages] = React.useState(0);
  const observer = React.useRef();

  React.useEffect(() => {
    // generating the 1st page on Component Mounting
    updateItems();
    setPages((pages) => pages + 1);
  }, []);

  const lastItemRef = React.useCallback(
    (node) => {
      // ensuring redundant calls are not made once the data is already BEING updated
      if (isLoading) return;
      if (observer.current) observer.current.disconnect();

      observer.current = new IntersectionObserver((entries) => {
        if (entries[0].isIntersecting && hasMore) {
          if (pages < MAX_PAGES) {
            // adding more data only if:
            // 1. MORE data exists ("hasMore" - simulated with "pages < MAX_PAGES")
            // 2. the last item is visible on the screen (using the "IntersectionObserver")
            updateItems();
            setPages((pages) => pages + 1);
          } else {
            setHasMore(false);
          }
        }
      });

      if (node) observer.current.observe(node);
    },
    [isLoading, hasMore]
  );

  const updateItems = async () => {
    setIsLoading(true);
    // simulating asynchronous nature of api (which is the general use case for Infinite Scroll)
    await new Promise((resolve) => setTimeout(resolve, 1000));

    setItems((currItems) => {
      const lastItem = currItems.length;
      const updatedItems = [...currItems];
      for (let i = 1; i <= 5; i++) {
        const item = lastItem + i;
        updatedItems.push(item);
      }
      return updatedItems;
    });

    setIsLoading(false);
  };

  return (
    <React.Fragment>
      <h1>Infinite Scroll Demo</h1>
      {items.map((item, index) =>
        index + 1 === items.length ? (
          <Item reference={lastItemRef} key={index}>
            {item}
          </Item>
        ) : (
          <Item key={index}>
            {item}
          </Item>
        )
      )}
      {isLoading && <div className="loader" />}
    </React.Fragment>
  );
};
Enter fullscreen mode Exit fullscreen mode

Update

As pointed out by some people in the comments, it can lead to performance degradation, so its suggested that when using infinite scroll for large list of items (around 250+ items), you should create the following CSS class:

.hidden {
    visibility: hidden !important;
}
Enter fullscreen mode Exit fullscreen mode

and add it to your items when they are not in the viewport.

Projects using this Implementation

Smartsapp (Previous Messages on scroll up)

Web-app: https://smartsapp-ba40f.firebaseapp.com

GitHub logo ruppysuppy / SmartsApp

💬📱 An End to End Encrypted Cross Platform messenger app.

Smartsapp

A fully cross-platform messenger app with End to End Encryption (E2EE).

Demo

NOTE: The features shown in the demo is not exhaustive. Only the core features are showcased in the demo.

Platforms Supported

  1. Desktop: Windows, Linux, MacOS
  2. Mobile: Android, iOS
  3. Website: Any device with a browser

Back-end Setup

The back-end of the app is handled by Firebase.

Basic Setup

  1. Go to firebase console and create a new project with the name Smartsapp
  2. Enable Google Analylitics

App Setup

  1. Create an App for the project from the overview page
  2. Copy and paste the configurations in the required location (given in the readme of the respective apps)

Auth Setup

  1. Go to the project Authentication section
  2. Select Sign-in method tab
  3. Enable Email/Password and Google sign in

Firestore Setup

  1. Go to the project Firestore section
  2. Create firestore provisions for the project (choose the server nearest to your location)
  3. Go to the Rules

Pizza Man (Previous Orders on scroll down)

Web-app: http://pizza-man-61510.firebaseapp.com/

GitHub logo ruppysuppy / Pizza-Man

🍕🛒 An e-commerce website to order pizza online

Pizza Man Project

An E-Commerce website for ordering Pizza Online

Demo

NOTE: The features shown in the demo is not exhaustive. Only the core features are showcased in the demo.

Tools used

  1. React: To create the Single Page App
  2. React-Router: For Routing
  3. Redux: For State Management
  4. Firebase: As a DataBase

Firebase Setup

You need to create a firebase configeration file holding the firebase settings in the path /src/firebase/config.js. The required format is:

const firebaseConfig = {
    apiKey: "API-KEY",
    authDomain: "AUTH-DOMAIN.firebaseapp.com",
    databaseURL: "DATABASE-URL.firebaseio.com",
    projectId: "PROJECT-ID",
    storageBucket: "STORAGE-BUCKET.appspot.com",
    messagingSenderId: "MESSAGING-SENDER-ID",
    appId: "APP-ID",
    measurementId: "MEASUREMENT-ID",
};

export default firebaseConfig;
Enter fullscreen mode Exit fullscreen mode

Data needs to be stored in the following format:

[
    {
        name: "CATEGORY NAME",
        items: [
            {
                desc: "PIZZA DESCRIPTION",
                id: "ID",
                img: "IMAGE LINK",
                name
Enter fullscreen mode Exit fullscreen mode

Finding personal finance too intimidating? Checkout my Instagram to become a Dollar Ninja

References

YouTube

  1. Infinite Scrolling With React - Tutorial (Web Dev Simplified)

Smashing Magazine

  1. Infinite Scroll: Let’s Get To The Bottom Of This

Thanks for reading

Reach out to me on:

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Terabox Video Player