How to create a page loader in ReactJS

The page loader can be a loading spinner or can be any animation that is being shown when some data from API is fetching. After the data has been rendered the page loader will stop. We create a page loader to let the user know that the data is rendering into reactJS.

In this article, we will be learning how to,

  • Create a page loader component in ReactJS
  • Managing the loading state of the page loader in ReactJS.

Create a page loader in ReactJS

  • Create a component where the data will be rendering and use Rest API to fetch the data.
import React, { useEffect, useState } from "react";

const App = () => {

  // fetch data from rest api
  const [comments, setComments] = useState([])
  useEffect(() => {
    fetch('https://jsonplaceholder.typicode.com/comments')
      .then(res => res.json())
      .then(data => setComments(data))
  }, [])

  return (
    <div className="min-h-screen">


    </div>
  );
}

export default App

Note: Here, we are fetching data from a fake API in the App component. To know about fetching data using Rest APIs, Read This Article.

  • Console.log the data and check if the data is being loaded correctly.
console.log(comments)

As the above picture has shown, the data is being rendered correctly in the browser DOM.

  • Now, show the data which is being rendered in the browser and add some styles to it so that it looks pleasant.
import React, { useEffect, useState } from "react";

const App = () => {

  // fetch data from rest api
  const [comments, setComments] = useState([])
  useEffect(() => {
    fetch('https://jsonplaceholder.typicode.com/comments')
      .then(res => res.json())
      .then(data => setComments(data))
  }, [])
  console.log(comments)
  return (
    <div className="min-h-screen grid grid-cols-3 gap-5 m-8">

      {
        comments.map(comment =>
          <div className="border-4 border-red-500 p-5 bg-white">
            <h3 className="text-xl text-gray-800">Post ID: {comment.postId}</h3>
            <h3 className="text-2xl text-gray-800">Name: {comment.name}</h3>
            <h3 className="text-2xl text-gray-800">Email: {comment.email}</h3>
            <p className="pt-8 text-gray-800">{comment.body}</p>
          </div>
        )
      }
    </div>
  );
}

export default App

Note: We are using Tailwind CSS and Daisy UI to style the component. To know more about this, Read This Article.

Create A Page Loader Component in ReactJS

  • Create a component for page loader,

import React from 'react';

const PageLoader = () => {
    return (
        <div className='h-96 flex justify-center items-center'>
            <div>
                <progress class="progress bg-white w-56"></progress>
                <h1 className="text-6xl">Loading...</h1>
            </div>
        </div>
    );
};

export default PageLoader;

Write these above codes on that page loader component.

Note: Any kind of page loader can be used. This is just a demonstration of a simple page loader.

Manage Loading State of Page Loader in ReactJS

  • Declare a state with a boolean value for the loader state in the component where the data from API is being fetched.
  // declare loading state
  const [loading, setLoading] = useState(false)

Note: By default, this value will be false. Because at the initial state of fetching the data, we don’t want to show the page loader.

  • Set the state as true at the very beginning of fetching the data and make it false right after the data has been fetched.
useEffect(() => {
    setLoading(true)
    fetch('https://jsonplaceholder.typicode.com/comments')
      .then(res => res.json())
      .then(data => {
         setComments(data)
         setLoading(false)
      })
    
  }, [])
  • Create a condition based on loading and return the page loader component at the bottom of the function.
//
  if(loading){
    return <PageLoader />
  }
  • Call this page loader based on the condition in JSX; if the value of loading is true, then and only then this page loader will be visible. Here is what the complete code looks like.
import React, { useEffect, useState } from "react";
import PageLoader from "./components/PageLoader";

const App = () => {
  // declare loading state
  const [loading, setLoading] = useState(false)

  // fetch data from rest api
  const [comments, setComments] = useState([])
  useEffect(() => {
    setLoading(true)
    fetch('https://jsonplaceholder.typicode.com/comments')
      .then(res => res.json())

      .then(data => {
        setComments(data)
        setLoading(false)
      })

  }, [])
  // console.log(comments)

  if (loading) {
    return <PageLoader />
  }

  return (
    <div >
      <div className="min-h-screen grid grid-cols-3 gap-5 m-8">

        {
          comments.map(comment =>
            <div className="border-4 border-red-500 p-5 bg-white">
              <h3 className="text-xl text-gray-800">Post ID: {comment.postId}</h3>
              <h3 className="text-2xl text-gray-800">Name: {comment.name}</h3>
              <h3 className="text-2xl text-gray-800">Email: {comment.email}</h3>
              <p className="pt-8 text-gray-800">{comment.body}</p>
            </div>
          )
        }
      </div>
    </div>
  );
}

export default App

While the data is rendering, this page loader will be visible. And it will disappear, once the data has been rendered.