Sobre almas e sincronias

Li uma vez que durante o processo da criação, não éramos dois, mas sim Um. Hermafrodita. Um ser completo e autossuficiente. Então não procriávamos. Logo, a força divina, responsável por nós e a quem…

Smartphone

独家优惠奖金 100% 高达 1 BTC + 180 免费旋转




Infinite Scroll With Photo Gallery in React

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:

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.

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:

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.

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.

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!

Add a comment

Related posts:

Sing me a song of your story

Cats is a feline fever dream. And quite possibly the cinematic experience of the year. Not because it is the best film, or even a great one, but because of its sheer audacity to be such an…

Why traveling comes with a lot of responsibility?

I first heard about Rotary International in 2010. One of my dad’s friends was a Rotarian, and because I was looking to go on an exchange program, I started getting involved in what, with the time…