Create Infinite Scroll Images in Remix

Banner for a MediaJam post

Odewole Babatunde Samson

Introduction

Building web applications involves displaying text, videos, and images to users. Sometimes, the sheer size of these assets could cause application lag; therefore, there is a need to display these assets in bits to users.

Developers have devised several means of compressing images; one that stands out is using pagination to enhance user experience. The use of an infinite scroll has proven to provide a better user experience. Building an infinite scroll into projects has gotten even easier with the introduction of the react-infinite-scroll-component.

What We Will be Building

This tutorial will walk us through implementing infinite scroll in an image gallery using the react-infinite-scroll-component with Remix.

SandBox

The completed demo for this project is in a CodeSandbox. Fork it to run the code.

The source code is available here.

What Exactly is Infinite Scroll?

Infinite scroll is an interactive feature that automatically loads more content as the user scrolls through the page, creating a seemingly endless page.

The interactivity has successfully eliminated the friction of pagination and led to increasing engagement. There is little wonder we would see it on almost all social media platforms and E-commerce websites.

“Just a few more shoes to check…." But you never get to the end of the seemingly endless list of shoes before you doze right off!

This tutorial will focus on leveraging the react-infinite-scroll-component to achieve infinite scroll.

Prerequisites

This tutorial assumes that we have the following:

  • Installation of Node.js on our computer
  • Basic knowledge of JavaScript
  • Familiarity with Remix
  • Pixabay account

Creating a Remix Project

First, we need to run the command below in the terminal to set up a new Remix application.

1npx create-remix@latest remix-infinite-scroll

The command triggers a CLI where we can configure the application. The images below show the configuration options the CLI provides:

User-uploaded image: Screenshot_5.png

Next, we navigate into the project directory.

1cd remix-infinite-scroll

Then, run the command below to start the application.

1npm run dev

Remix will start a development environment accessible by default at http://localhost:3000.

Installing TailwindCSS

TailwindCSS is a utility-first CSS framework with classes to help us style web pages.

We install tailwindcss and its peer dependencies via npm, which generates tailwind.config.js and postcss.config.js.

1npm install -D tailwindcss postcss autoprefixer
2npx tailwindcss init -p

We need to add the paths to our template files in the tailwind.config.js file.

1//tailwind.config.js
2 module.exports = {
3 content: [
4 "./pages/**/*.{js,ts,jsx,tsx}",
5 "./components/**/*.{js,ts,jsx,tsx}",
6 ],
7 theme: {
8 extend: {},
9 },
10 plugins: [],
11 }

We should add the @tailwind directives for Tailwind’s layers to our ./styles/globals.css file.

1//globals.css
2 @tailwind base;
3 @tailwind components;
4 @tailwind utilities;

Installing react-infinite-scroll

React-infinite-scroll-component is a component to make all the infinite scrolling woes go away with just 4.15 kB! An infinite scroll that works and is super simple to integrate! The Pull Down to Refresh feature was added to make it more awesome.

To install the react-infinite-scroll-component in our project, we run the following terminal command.

1npm install --save react-infinite-scroll-component

Creating the Skeleton UI with Random Images

Before wading through an endless list of images, we’ll build a skeleton interface to lay the foundation of our gallery.

Creating the Image Component

The grid of images across each row shows a photo gallery. We create a component folder in the app directory, then create an ImageCard.jsx file and add the code block below:

1const ImageCard = ({ image }) => {
2 return (
3 <div className="max-w-sm rounded overflow-hidden shadow-lg">
4 <img src={image.webformatURL} alt="" className="w-full" />
5 <div className="px-6-py-4">
6 <div className="font-bold text-purple-500 text-xl mb-2">
7 Photo by Samson
8 </div>
9 <ul>
10 <li>
11 <strong>Views:</strong>
12 4000
13 </li>
14 <li>
15 <strong>Downloads:</strong>
16 5000
17 </li>
18 <li>
19 <strong>Likes:</strong>
20 50
21 </li>
22 </ul>
23 </div>
24 </div>
25 )
26}
27export default ImageCard;

Proceed to the app/routes/index.jsx file and import the ImageCard component.

At this point, the app/routes/index.jsx should look like this:

1import ImageCard from "../component/ImageCard";
2
3export default function Index() {
4
5 return (
6 <div className="container mx-auto">
7 <div className="grid grid-cols-3 gap-4">
8 <ImageCard/>
9 </div>
10 </InfiniteScroll>
11 </div>
12 );
13}

Our webpage should then look like this:

image-component-UI

Adding Dynamic Images

After setting up the basic UI skeleton for the page, the next thing to be done is to add dynamic images that populate automatically from an API. This article will be using the Pixabay API. To use the Pixabay API, we must sign up for an account to generate an API Key.

At the end of this setup, the app/routes/index.jsx should look like the below:

1import { useState, useEffect } from "react";
2import ImageCard from "../component/ImageCard";
3
4export default function Index() {
5 const [images, setImages] = useState([]);
6
7 useEffect(() => {
8 fetch(`https://pixabay.com/api/?key={PIXABAY_API_KEY}&q=yellow+flowers&image_type=photo&pretty=true?_limit=10`)
9 .then(res => res.json())
10 .then(data => {
11 console.log(data)
12 setImages(data.hits);
13 setIsLoading(false);
14 }).catch(err => console.log(err));
15 }, [])
16 return (
17 <div className="container mx-auto">
18 <div className="grid grid-cols-3 gap-4">
19 {images.map(image => (
20 <ImageCard key={image.id} image={image} />
21 ))}
22 </div>
23 </div>
24 );
25}

In the app/routes/index.jsx, we did the following:

  • Used the useEffect Hooks to fetch dynamic images from the Pixabay API in the code above
  • Set the limit of the image to 10 on the mounts of the app
  • Loop through the imported image array to render each image

Instead of Pixabay, we could use data of images stored locally or retrieved from an API.

By now, our UI should look like this:

dynamic-image-UI

Implementing the Infinite Scroll

To create a seemingly endless page with the react-infinite-scroll-component, import the dependency into the app/routes/index.jsx file.

1import InfiniteScroll from 'react-infinite-scroll-component';

We then need to render the InfiniteScroll component to our images like this:

1<InfiniteScroll
2 dataLength={images.length} //This is important field to render the next data
3 next={getMoreImages}
4 hasMore={true}
5 loader={<h4>Loading...</h4>}
6 endMessage={
7 <p style={{ textAlign: 'center' }}>
8 <b>Yay! You have seen it all</b>
9 </p>
10 }
11 >
12 <div className="grid grid-cols-3 gap-4">
13 {images.map(image => (
14 <ImageCard key={image.id} image={image} />
15 ))}
16 </div>
17</InfiniteScroll>

The code snippet above passed the InfiniteScroll component with the dataLength, next, loader, and endMessage properties.

Next, we need to declare the getMoreImages() function that'll get new images from the Pixabay API while scrolling through the web pages.

1const getMoreImages = async () => {
2 const response = await fetch(`https://pixabay.com/api/?key={PIXABAY_API_KEY}&q=yellow+flowers&image_type=photo&pretty=true?_start=${images.length}&_limit=10`);
3 const newImages = await response.json();
4 setImages([...images, ...newImages.hits]);
5 setIsLoading(false);
6}

At this point, more images should automatically load as we navigate through the application in our browser.

infinite-scroll-application

Conclusion

In this post, we learned how to build a photo gallery with infinite scroll implemented using the react-infinite-scroll component and Pixabay APIs in Remix.

Resources

We may find these resources helpful:

Odewole Babatunde Samson

Software engineer and Technical writer

I am a self-driven and self-motivated software engineer in the blockchain development space and I love to impact more knowledge to people that is why I write about Javascript, React.js, web3.js, and Solidity