Building a Universal Higher-Order Component Page Loader for your React App

Loading screens are needed everywhere — don’t reinvent the wheel every time.

Paige Niedringhaus
Bits and Pieces

--

Screenshot of the universal loader animation.

Introduction

If you’ve worked in web development for any length of time and ever needed to access a database or some other service containing data before showing a page to a user, you’ve encountered the need for a loading screen.

Even with the ever-improving speed and availability we’re afforded by the Internet today, it can still take more than mere milliseconds to fetch data off a server (especially when it’s a large amount of data you need, or that data needs to be transformed by the browser before displaying it onscreen) or process a request from the browser (like placing an order online). The real question might actually be: when don’t we need loading screens in our web applications?

There’s a million reasons why some visual loading indication might be necessary, but what I’m here to tell you about is how you can build a single, flexible, higher-order component loader, and use it in multiple places in your React application with minimal effort.

This post will not cover publishing the loader component and reusing it in other projects, but if that’s something you’re interested in, I recommend you try Bit. Bit is a tool and a component hub that makes it easy to publish, document, and organize React components. You can read more about it here:

Example: exploring published React components on Bit.dev

React’s Higher-Order Components

What the heck is an HOC?

Before we go any further, let’s talk about higher-order components (hereafter referred to only as HOCs) and what they are in React.

The official React documentation explains HOCs pretty well, if a bit abstractly.

“A higher-order component (HOC) is an advanced technique in React for reusing component logic. HOCs are not part of the React API, per se. They are a pattern that emerges from React’s compositional nature.” — React Docs

The piece to focus on here is the phrase “reusing component logic.” In laymen’s terms, HOCs are a way to share the same functionality across multiple components, without having to rewrite said functionality within each component.

This is achieved by the higher-order component actually being a function that takes in one component and returns a new component. HOCs are not components, in the traditional React sense, they are functions.

If you’ve ever used the state management library Redux and its connect() function, you’ve already used higher-order components, even if you weren’t aware of it.

Examples of where HOCs could also come in handy are: maintaining the state of logged-in users in an application so they’re shown the correct views in certain components OR having a single component that can add a uniform loading screen to all the pages that need it.

See where I’m going with this? 😉

And here’s the other cool thing to note about HOCs: even though they’ve been around since the early days of React when classes ruled — before Hooks came in to steal the state show, HOCs can work with both class-based components and stateless functional components. Pretty sweet if you’ve got a legacy app that you’re maintaining or you’re only starting to upgrade to Hooks now.

So without further ado, let’s get to the code and make this universal loading component a reality.

Building a Loading Higher-Order Component

The code for the loading HOC isn’t very complicated, in actuality. Here’s a code snippet of the universal loader component my team uses in our own application.

IsLoadingHOC.js

The IsLoadingHOC.js component providing a universal page loading animation for any component that needs it.

You’ll notice in the code that the IsLoadingHOC variable declared takes in two parameters: a WrappedComponent and a loadingMessage.

The WrappedComponent is whatever component needs to display onscreen once the loader’s isLoading state is set to false, and the loadingMessage allows for a custom message to be passed in to display while the IsLoadingHOC component is active. In this way, the app can pass different messages to users depending on what page is currently loading.

Messages could be something like “Please wait while we fetch your data”, “Please wait while we place your order”, or “Please wait while we search for item XYZ” — you get the idea.

The one piece of state inside of the HOC function is the const [isLoading, setLoading] = useState(true); which defaults the isLoadingHOC component to show as soon as a new React component wrapped in this HOC is mounted into the DOM.

The function inside the HOC function: setLoadingState, is the function passed to (and triggered by) whatever the wrapped component is, which tells the IsLoadingHOC component to show itself or not.

The return statement wrapped inside of the HOC function is the actual JSX code that will render the new component (which is really just an existing component with the added loading functionality provided by this HOC function). Feel free to sub in any loading animation you’d like for this <LogoAnimationLoader />.

And finally, the HOC function itself is returned at the very bottom of the code snippet, because, as I said earlier, HOCs are functions that take in one component and return a new, enhanced component.

Side note: If you’re curious about the <LogoAnimationLoader /> component in the JSX, it is actually a custom loading animation made for our team with the help of Lottie. Lottie is a library that parses Adobe After Effects animations exported as json then renders them natively on mobile and on the web. But that’s for another post — back to the HOC loading code.

Using the Loading HOC in my React App

With the universal loading component created, it’s time to add it to the component that needs the loader now. The example I’ll be showing is using the loader with a page that generates and displays downloadable reports for users.

Combining the IsLoadingHOC with the Report Component

Here is a slimmed-down version of <ReportPage /> component to illustrate how to add the IsLoadingHOC to it. As you can tell, this code has been condensed for clarity, but the pieces you need to see for the HOC loading screen to make sense are present.

ReportPage.js

The `ReportPage` component with the `IsLoadingHOC` wrapped around it to give it the loading animation.

In the code shown above, you can see that the setLoading() function is passed in at the start of the ReportPage component. This is the prop that is passed through the IsLoadingHOC, which wraps the ReportPage component, and makes it possible to turn on or off the loading animation.

For this particular case, as soon as the page loads, the React useEffect() Hook kicks in and sets the HOC loader’s state to false. Then, if a user chooses to generate a new report, contained in the <ReportGenerator /> component displayed in the JSX, the generateReport() report function once more sets the IsLoadingHOC's loading state to true, courtesy of the setLoading() function. As soon as the reportService.generateReport() function successfully returns, setLoading() sets the visibility of the IsLoadingHOC() back to false.

The bottom of this file where the export statement lives is the key to integrating the IsLoadingHOC with the ReportPage . In order for the ReportPage component (the WrappedComponent in this case) to inherit the loader’s properties, it gets wrapped by the IsLoadingHOC and is passed the string “Please wait as we load your data”, which is the customizable message prop the IsLoadingHOC expects as its second argument.

export default IsLoadingHOC(ReportPage, 'Please wait as we load your data.');

And with that, this is the page loading animation we end up seeing while data is loading.

The pleasant (and easy to implement), full-page higher order component loader at work on the Report’s page.

Ta da!

The best part? This IsLoadingHOC component can be used with any other component in the application that needs an animated loader while data’s being fetched or submitted.

Just pass in the setLoading() function to the component to be wrapped with the loading animation, add a custom message to accompany it if you so desire, and you’re pretty much ready to go.

Conclusion

The Internet experience is fast and only getting faster, but the things we’re asking it to do are complex and only getting more so. Which means loading screens to let users know something’s happening are more imperative now than ever before.

Early on in React, a pattern emerged taking advantage of the framework’s compositional nature, and it was dubbed “higher-order components.” The name is a little intimidating, but the idea of HOCs is: give the HOC some logic you want to share across components in the app, pass a component into the HOC that you want to have that logic, and the HOC spits out a new component complete with that logic. Simple as that.

Higher-order components can be used to maintain state as a user navigates around an application, they can be used to abstract data fetching for components that behave similarly but have different data sources and they can be used to add functionality needed in multiple places, like loading screens. And the best part? The HOCs can be used with class-based components and functional components.

Check back in a few weeks — I’ll be writing more about JavaScript, React, ES6, or something else related to web development.

Thanks for reading. I hope if you have multiple places in your React application in need of a loading animation (or any sort of reused functionality, really), you’ll consider creating a reusable HOC to simplify your life. Why write the same functionality more than once, there’s really no need. 🙂

If you enjoyed reading this, you may also enjoy some of my other free pieces:

--

--

Staff Software Engineer at Blues, previously a digital marketer. Technical writer & speaker. Co-host of Front-end Fire & LogRocket podcasts