'How to have a loading screen until all my components are mounted in React

I do not have any API calls for my react app, I want to have a loading page while all my components are being mounted (including all children). My page does take few seconds to load.

The issue I am having is that I do not want to use setTimeout as my page can load for any amount of seconds. I just want to show a loading screen until my actual page is ready to show.



Solution 1:[1]

Try the load event like so (assuming you're talking about react hooks implementation.) :-

const Component = () => {
const [isLoading, setIsLoading] = React.useState(true);

const handleLoading = () => {
setIsLoading(false);
}

useEffect(()=>{
window.addEventListener("load",handleLoading);
return () => window.removeEventListener("load",handleLoading);
},[])

return !isLoading ? (
{*/ your content here */}
):({*/ your loader */})

}

Solution 2:[2]

Just add a pure CSS loader to your index.html of the html file.

Working sandbox code here : https://codesandbox.io/s/silly-frog-z7ju3?file=/src/index.js:288-438

    <title>React App</title>
    <style>
      #root .loader-container {
        background-color: #0cbaba;
        background-image: linear-gradient(315deg, #0cbaba 0%, #380036 74%);
        height: 100vh;
        display: flex;
        align-items: center;
        justify-content: center;
      }

      #root {
        /* display: none; */
      }
      .sk-chase {
        width: 40px;
        height: 40px;
        position: relative;
        animation: sk-chase 2.5s infinite linear both;
      }

      .sk-chase-dot {
        width: 100%;
        height: 100%;
        position: absolute;
        left: 0;
        top: 0;
        animation: sk-chase-dot 2s infinite ease-in-out both;
      }

      .sk-chase-dot:before {
        content: "";
        display: block;
        width: 25%;
        height: 25%;
        background-color: #fff;
        border-radius: 100%;
        animation: sk-chase-dot-before 2s infinite ease-in-out both;
      }

      .sk-chase-dot:nth-child(1) {
        animation-delay: -1.1s;
      }
      .sk-chase-dot:nth-child(2) {
        animation-delay: -1s;
      }
      .sk-chase-dot:nth-child(3) {
        animation-delay: -0.9s;
      }
      .sk-chase-dot:nth-child(4) {
        animation-delay: -0.8s;
      }
      .sk-chase-dot:nth-child(5) {
        animation-delay: -0.7s;
      }
      .sk-chase-dot:nth-child(6) {
        animation-delay: -0.6s;
      }
      .sk-chase-dot:nth-child(1):before {
        animation-delay: -1.1s;
      }
      .sk-chase-dot:nth-child(2):before {
        animation-delay: -1s;
      }
      .sk-chase-dot:nth-child(3):before {
        animation-delay: -0.9s;
      }
      .sk-chase-dot:nth-child(4):before {
        animation-delay: -0.8s;
      }
      .sk-chase-dot:nth-child(5):before {
        animation-delay: -0.7s;
      }
      .sk-chase-dot:nth-child(6):before {
        animation-delay: -0.6s;
      }

      @keyframes sk-chase {
        100% {
          transform: rotate(360deg);
        }
      }

      @keyframes sk-chase-dot {
        80%,
        100% {
          transform: rotate(360deg);
        }
      }

      @keyframes sk-chase-dot-before {
        50% {
          transform: scale(0.4);
        }
        100%,
        0% {
          transform: scale(1);
        }
      }
    </style>
  </head>

  <body>
    <noscript>
      You need to enable JavaScript to run this app.
    </noscript>
    <div id="root">
      <div class="loader-container">
        <div class="loader">
          <div class="sk-chase">
            <div class="sk-chase-dot"></div>
            <div class="sk-chase-dot"></div>
            <div class="sk-chase-dot"></div>
            <div class="sk-chase-dot"></div>
            <div class="sk-chase-dot"></div>
            <div class="sk-chase-dot"></div>
          </div>
        </div>
      </div>
    </div>

 
  </body>
</html>

I have also added a little bit of code to calculate the component tree mount time. The code sandbox mounts about 400,000 elements and it takes 3 seconds to mount the whole tree.

const t0 = performance.now();

function renderCallback(e) {
  console.log("Rendering done?", e);
  const t1 = performance.now();

  console.log(`Mount took ~${(t1 - t0) / 1000} seconds.`);
}

const rootElement = document.getElementById("root");

ReactDOM.render(
  <StrictMode>
    <App />
  </StrictMode>,
  rootElement,
  renderCallback
);

A simple callback when rendering is completed

The ReactDOM.render method provides a callback which fires after the mount has been completed.

ReactDOM.render(element, container[, callback])

You can do some interesting things here like add or remove classes/elements and do even more things to show good pre loading UX.

Just show a static loader before the UI is mounted

But to just show something until mounted you just have to put something inside the div you will render the react tree into. Once react completes its render everything inside that element will be replaced.

const rootElement = document.getElementById("root");
ReactDOM.render(<MyAwesomeComponentTree />,rootElement);

<body>
    <div id="root">
       <!-- Everything here will be replaced by React -->
    </div>
</body>

https://reactjs.org/docs/react-dom.html#render

Solution 3:[3]

You could just set a loader while your page isn't ready. You just need to set a state like :

const [isReady, setIsReady] = React.useState(false);

And then you can do :

if(!isReady) {
  return <>Loading...</>
}

return (
  <>
     {*/ your content here */}
  </>
);

When you will set your isReady to true, then your component will be rerendered with the content of your page.

Solution 4:[4]

         const [loading,setLoading] = useState(false);

         //on button clicked

         const  handleDataComponent = ()=>{
         setLoading(!loading);
         }

         return (
         {loading &&
         <div>{DataComponent here}</div>
         }
         )

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Dehan
Solution 3 Quentin Grisel
Solution 4 Jerrysofttechy