Infinite Scroll With Photo Gallery in React
By: Michael Tong
Tags: Animation, CSS, Web Development, React, JavaScript

Photo by kimi lee on Unsplash

To understand the context of what and how infinite scroll works, you can read the following article: https://medium.com/dev-genius/infinite-scroll-with-photo-gallery-in-vanilla-javascript-9dc1d3896cf7

This article is pretty much a react version of the article I just included. The focus of this article is to understand how infinite scroll works as well as how to display a loading indicator when images are being retrieved. By reading this article, I assume you have background and experience coding in react and javascript in general.

As mentioned in the article provided, we have to understand three things:

HTML that contains the images and a loading indicator

a CSS file that controls the animation of loading indicator and how big the images are

a javascript file that contains the logic to get images, the logic to detect when the user scrolls to the bottom of the page, as well as a timeout logic to give time to load new images when the user scroll down to get more images.

If this assignment is done in plain vanilla javascript, we have to use opacity to hide/display the loading indicator:

Scroll down to the bottom and you will see .loading and .loading.show CSS rule. This is the part where if the div holding the loading indicator has a subclass of show(added when the user scrolls to the bottom of the page), the loading icons show up.

With react, we no longer need to use opacity, and instead, we can jsx to conditionally display the loading indicator.

Photo by Ferenc Almasi on Unsplash

React allow us to modularize a lot of our code and what that means is we can also modularize the loading indicator as well as the photo gallery.

Base on that, we can divide our code into the following:

photo gallery component

loading indicator component

Wow! The structure looks so different than what we have in the vanilla javascript implementation, which has an HTML, js, and a CSS file.

Technically, we can separate js and CSS files into one used for photo gallery and loading indicator. However, we can accidentally mix up CSS rules if there are CSS rules from the photo gallery component and loading indicator component named the same.

What will happen is one CSS rule overwrites another and that’s why I kept everything into one HTML, one js, and one CSS file only.

To start, you need to run npx create-react-project infinite-gallery.

Afterward, under the src folder create a components folder and create a PhotoGallery.js:

Let’s break down into chunks that we can understand. In our constructor, we set our initial state to have a placeholder for a list of photos, the current page to fetch photos from, and as well as a loading boolean. This boolean helps us determine whether to show the loading indicator or not. The boolean only gets shifted to true only when the user scrolls to the bottom of the page.

Also within the constructor, we added an onscroll event listener. We get scrollTop, clientHeight, and scrollHeight, which is used to determine whether or not we are on the bottom of the page:

If we are on the bottom of the page, the loading state of the photo gallery gets set to true, effectively rendering the loading indicator. Afterward, we increment the page count so on our API call we will be getting different images every time.

After we retrieve the images, we add our images on top of the ones we have and set the loading state to false. On top of all this, we wrap the API call and setState in a debounce function. What this will do is wait for 1000 ms(can be as long as you want) before the API gets called. This is to prevent excessive API calls to be made to get images since the user can be scrolling to the bottom of the page again before the new images are retrieved.

How about when we initially load the page? That’s where componentDidMount comes in. With the componentDidMount lifecycle method, we can get photos and populate the page before the page is even rendered.

Once the page renders, we populate the photos we have and if the loading state is turned on, then the loading indicator will show up.

Photo by Jen Theodore on Unsplash

We talked enough about how the photo gallery. How about the loading indicator? How does that look?

Under the src/components folder, create a PhotoGallery.js with the following contents:

Similar to what we have seen in the vanilla javascript implementation, we have keyframes that dictates how the dots within the loading indicator moves.

However, we need to wrap the keyframes into global CSS in order for other CSS rules that use the animation key-frames to understand what they are.

Within the ball CSS, we set its width and height as well as the nature and the duration of the animation. AnimationTimingFunction determines the nature, animationDuration determines how long it will take, and animationIteration determines how frequently the animation occurs.

Photo by monika karaivanova on Unsplash

One might ask…why creating this in a react application rather than a simple vanilla javascript application?

First of all, react provides an amazing mechanism to deal with the initial loading of data in the page. With vanilla javascript, you have to create a function to retrieve the data from an API and append it to a specific element in the HTML via jquery. That’s not necessary the cleanliest way of initializing some piece of data in a page.

What if there are changes to the class name or the id of the particular div? Now your code is all broken and you have to go into the javascript file and change the id/class that you used to query the div for the photos.

With react, you don’t need to worry about any of this! All you have to worry about is figuring the right lifecycle method to use and make the API call to dump the data into the local state. If the data is not ready, all you need is to set the loading state variable to true and show a loading indicator! That’s it! You don’t have to worry about using jquery to attach data to a specific node in the dom.

With that being said, understanding how infinite gallery is implemented in vanilla javascript will help us understand how dom-manipulation works. Furthermore, it helps understands the downside of mixing HTML, javascript, and CSS logic when all of this can be modularized into components.

That’s it! Happy coding!