Infinite Scroll With Photo Gallery in React

Michael Tong
Dec 2, 2020 · 5 min read
Infinite Scroll With Photo Gallery in React
Infinite Scroll With Photo Gallery in React
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.

Image for post
Image for post
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:

Image for post
Image for post

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.

Image for post
Image for post
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.

Image for post
Image for post
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!

Weekly Webtips

Explore the world of web technologies through a series of tutorials

Sign up for 💌 Weekly Newsletter

By Weekly Webtips

Get the latest news on the world of web technologies with a series of tutorial Take a look.

By signing up, you will create a Medium account if you don’t already have one. Review our Privacy Policy for more information about our privacy practices.

Check your inbox
Medium sent you an email at to complete your subscription.

Michael Tong

Written by

Coding is nothing but a renovation of ideas through fundamental concepts. Stay sharp and stay hungry to learn!

Weekly Webtips

Explore the world of web technologies through a series of tutorials

Michael Tong

Written by

Coding is nothing but a renovation of ideas through fundamental concepts. Stay sharp and stay hungry to learn!

Weekly Webtips

Explore the world of web technologies through a series of tutorials

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

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