DEV Community

Cover image for How to create a simple Loading Screen in React
Arjun Sharma
Arjun Sharma

Posted on • Edited on

How to create a simple Loading Screen in React

Hey devs 👋
So, recently I was trying to figure out how to create an awesome looking Loading Screens in React without installing npm packages and also which are simple to use. And I came around something that I want to share with you guys.

Final Result

Final Result

Star Wars

Creating SVG using Figma

Yes, we will be using Figma to create a SVG. Let's open up Figma in our desktop and create a new design file.

Figma

  • Now, create a Frame (by pressing F) and selecting any dimension. I will be using 1280 x 720.

  • After creating the Frame, let's make the background a bit darker so that we can see everything perfectly.

  • Now, create a Text in the Frame and increase it's font-size. I will be using 64px.(Make sure the text width and height perfectly fits)

Loading SVG Text

  • Now, Right-click on the Text and select Outline Stroke

Outline Stroke

  • Now, let's remove the Fill color from the text and add a Stroke color having width of 5px. Now, it should look something like this...

Final SVG

  • Now, Right-click on the text and Copy as SVG.

Initial Project Setup

First, let's create the React app by using the following command
npx create-react-app loading-screen

Now, let's delete all the files in src directory inside the loading-screen app except the index.js, index.css, app.js

Loading Component

Let's begin by creating the Loading Component. So, in the src folder, create a new file named Loading.jsx and Loading.css

  • Create a div with id "loader-container" inside the Loading Component
  • Inside the div paste the SVG and add an id "loader"


import './Loading.css'
const Loading=()=>{
  return(
    <div id="loader-container">
      <svg id="loader" width="285" height="59" viewBox="0 0 285 59" fill="none" xmlns="http://www.w3.org/2000/svg">
<mask id="path-1-outside-1_1_6" maskUnits="userSpaceOnUse" x="0.636353" y="0.818176" width="284" height="58" fill="black">
<rect fill="white" x="0.636353" y="0.818176" width="284" height="58"/>
<path d="M5.63635 53V6.45454H11.2727V48H32.9091V53H5.63635Z"/>
<path d="M79.0966 29.7273C79.0966 34.6364 78.2102 38.8788 76.4375 42.4545C74.6648 46.0303 72.2329 48.7879 69.142 50.7273C66.0511 52.6667 62.5208 53.6364 58.5511 53.6364C54.5814 53.6364 51.0511 52.6667 47.9602 50.7273C44.8693 48.7879 42.4375 46.0303 40.6648 42.4545C38.892 38.8788 38.0057 34.6364 38.0057 29.7273C38.0057 24.8182 38.892 20.5758 40.6648 17C42.4375 13.4242 44.8693 10.6667 47.9602 8.72727C51.0511 6.78787 54.5814 5.81818 58.5511 5.81818C62.5208 5.81818 66.0511 6.78787 69.142 8.72727C72.2329 10.6667 74.6648 13.4242 76.4375 17C78.2102 20.5758 79.0966 24.8182 79.0966 29.7273ZM73.642 29.7273C73.642 25.697 72.9678 22.2955 71.6193 19.5227C70.286 16.75 68.4754 14.6515 66.1875 13.2273C63.9148 11.803 61.3693 11.0909 58.5511 11.0909C55.7329 11.0909 53.1799 11.803 50.892 13.2273C48.6193 14.6515 46.8087 16.75 45.4602 19.5227C44.1269 22.2955 43.4602 25.697 43.4602 29.7273C43.4602 33.7576 44.1269 37.1591 45.4602 39.9318C46.8087 42.7045 48.6193 44.803 50.892 46.2273C53.1799 47.6515 55.7329 48.3636 58.5511 48.3636C61.3693 48.3636 63.9148 47.6515 66.1875 46.2273C68.4754 44.803 70.286 42.7045 71.6193 39.9318C72.9678 37.1591 73.642 33.7576 73.642 29.7273Z"/>
<path d="M88.2954 53H82.3864L99.4773 6.45454H105.295L122.386 53H116.477L102.568 13.8182H102.205L88.2954 53ZM90.4773 34.8182H114.295V39.8182H90.4773V34.8182Z"/>
<path d="M144 53H129.636V6.45454H144.636C149.152 6.45454 153.015 7.38636 156.227 9.25C159.439 11.0985 161.901 13.7576 163.614 17.2273C165.326 20.6818 166.182 24.8182 166.182 29.6364C166.182 34.4848 165.318 38.6591 163.591 42.1591C161.864 45.6439 159.348 48.3258 156.045 50.2045C152.742 52.0682 148.727 53 144 53ZM135.273 48H143.636C147.485 48 150.674 47.2576 153.205 45.7727C155.735 44.2879 157.621 42.1742 158.864 39.4318C160.106 36.6894 160.727 33.4242 160.727 29.6364C160.727 25.8788 160.114 22.6439 158.886 19.9318C157.659 17.2045 155.826 15.1136 153.386 13.6591C150.947 12.1894 147.909 11.4545 144.273 11.4545H135.273V48Z"/>
<path d="M181.273 6.45454V53H175.636V6.45454H181.273Z"/>
<path d="M229.483 6.45454V53H224.028L198.665 16.4545H198.21V53H192.574V6.45454H198.028L223.483 43.0909H223.937V6.45454H229.483Z"/>
<path d="M272.58 21C272.08 19.4697 271.42 18.0985 270.602 16.8864C269.799 15.6591 268.837 14.6136 267.716 13.75C266.61 12.8864 265.352 12.2273 263.943 11.7727C262.534 11.3182 260.989 11.0909 259.307 11.0909C256.549 11.0909 254.042 11.803 251.784 13.2273C249.526 14.6515 247.731 16.75 246.398 19.5227C245.064 22.2955 244.398 25.697 244.398 29.7273C244.398 33.7576 245.072 37.1591 246.42 39.9318C247.769 42.7045 249.595 44.803 251.898 46.2273C254.201 47.6515 256.792 48.3636 259.67 48.3636C262.337 48.3636 264.686 47.7955 266.716 46.6591C268.761 45.5076 270.352 43.8864 271.489 41.7955C272.64 39.6894 273.216 37.2121 273.216 34.3636L274.943 34.7273H260.943V29.7273H278.67V34.7273C278.67 38.5606 277.852 41.8939 276.216 44.7273C274.595 47.5606 272.352 49.7576 269.489 51.3182C266.64 52.8636 263.367 53.6364 259.67 53.6364C255.549 53.6364 251.928 52.6667 248.807 50.7273C245.701 48.7879 243.276 46.0303 241.534 42.4545C239.807 38.8788 238.943 34.6364 238.943 29.7273C238.943 26.0454 239.436 22.7348 240.42 19.7954C241.42 16.8409 242.83 14.3258 244.648 12.25C246.466 10.1742 248.617 8.58333 251.102 7.47727C253.587 6.37121 256.322 5.81818 259.307 5.81818C261.761 5.81818 264.049 6.18939 266.17 6.93181C268.307 7.65908 270.208 8.69696 271.875 10.0454C273.557 11.3788 274.958 12.9773 276.08 14.8409C277.201 16.6894 277.973 18.7424 278.398 21H272.58Z"/>
</mask>
<path d="M5.63635 53V6.45454H11.2727V48H32.9091V53H5.63635Z" stroke="white" stroke-width="10" mask="url(#path-1-outside-1_1_6)"/>
<path d="M79.0966 29.7273C79.0966 34.6364 78.2102 38.8788 76.4375 42.4545C74.6648 46.0303 72.2329 48.7879 69.142 50.7273C66.0511 52.6667 62.5208 53.6364 58.5511 53.6364C54.5814 53.6364 51.0511 52.6667 47.9602 50.7273C44.8693 48.7879 42.4375 46.0303 40.6648 42.4545C38.892 38.8788 38.0057 34.6364 38.0057 29.7273C38.0057 24.8182 38.892 20.5758 40.6648 17C42.4375 13.4242 44.8693 10.6667 47.9602 8.72727C51.0511 6.78787 54.5814 5.81818 58.5511 5.81818C62.5208 5.81818 66.0511 6.78787 69.142 8.72727C72.2329 10.6667 74.6648 13.4242 76.4375 17C78.2102 20.5758 79.0966 24.8182 79.0966 29.7273ZM73.642 29.7273C73.642 25.697 72.9678 22.2955 71.6193 19.5227C70.286 16.75 68.4754 14.6515 66.1875 13.2273C63.9148 11.803 61.3693 11.0909 58.5511 11.0909C55.7329 11.0909 53.1799 11.803 50.892 13.2273C48.6193 14.6515 46.8087 16.75 45.4602 19.5227C44.1269 22.2955 43.4602 25.697 43.4602 29.7273C43.4602 33.7576 44.1269 37.1591 45.4602 39.9318C46.8087 42.7045 48.6193 44.803 50.892 46.2273C53.1799 47.6515 55.7329 48.3636 58.5511 48.3636C61.3693 48.3636 63.9148 47.6515 66.1875 46.2273C68.4754 44.803 70.286 42.7045 71.6193 39.9318C72.9678 37.1591 73.642 33.7576 73.642 29.7273Z" stroke="white" stroke-width="10" mask="url(#path-1-outside-1_1_6)"/>
<path d="M88.2954 53H82.3864L99.4773 6.45454H105.295L122.386 53H116.477L102.568 13.8182H102.205L88.2954 53ZM90.4773 34.8182H114.295V39.8182H90.4773V34.8182Z" stroke="white" stroke-width="10" mask="url(#path-1-outside-1_1_6)"/>
<path d="M144 53H129.636V6.45454H144.636C149.152 6.45454 153.015 7.38636 156.227 9.25C159.439 11.0985 161.901 13.7576 163.614 17.2273C165.326 20.6818 166.182 24.8182 166.182 29.6364C166.182 34.4848 165.318 38.6591 163.591 42.1591C161.864 45.6439 159.348 48.3258 156.045 50.2045C152.742 52.0682 148.727 53 144 53ZM135.273 48H143.636C147.485 48 150.674 47.2576 153.205 45.7727C155.735 44.2879 157.621 42.1742 158.864 39.4318C160.106 36.6894 160.727 33.4242 160.727 29.6364C160.727 25.8788 160.114 22.6439 158.886 19.9318C157.659 17.2045 155.826 15.1136 153.386 13.6591C150.947 12.1894 147.909 11.4545 144.273 11.4545H135.273V48Z" stroke="white" stroke-width="10" mask="url(#path-1-outside-1_1_6)"/>
<path d="M181.273 6.45454V53H175.636V6.45454H181.273Z" stroke="white" stroke-width="10" mask="url(#path-1-outside-1_1_6)"/>
<path d="M229.483 6.45454V53H224.028L198.665 16.4545H198.21V53H192.574V6.45454H198.028L223.483 43.0909H223.937V6.45454H229.483Z" stroke="white" stroke-width="10" mask="url(#path-1-outside-1_1_6)"/>
<path d="M272.58 21C272.08 19.4697 271.42 18.0985 270.602 16.8864C269.799 15.6591 268.837 14.6136 267.716 13.75C266.61 12.8864 265.352 12.2273 263.943 11.7727C262.534 11.3182 260.989 11.0909 259.307 11.0909C256.549 11.0909 254.042 11.803 251.784 13.2273C249.526 14.6515 247.731 16.75 246.398 19.5227C245.064 22.2955 244.398 25.697 244.398 29.7273C244.398 33.7576 245.072 37.1591 246.42 39.9318C247.769 42.7045 249.595 44.803 251.898 46.2273C254.201 47.6515 256.792 48.3636 259.67 48.3636C262.337 48.3636 264.686 47.7955 266.716 46.6591C268.761 45.5076 270.352 43.8864 271.489 41.7955C272.64 39.6894 273.216 37.2121 273.216 34.3636L274.943 34.7273H260.943V29.7273H278.67V34.7273C278.67 38.5606 277.852 41.8939 276.216 44.7273C274.595 47.5606 272.352 49.7576 269.489 51.3182C266.64 52.8636 263.367 53.6364 259.67 53.6364C255.549 53.6364 251.928 52.6667 248.807 50.7273C245.701 48.7879 243.276 46.0303 241.534 42.4545C239.807 38.8788 238.943 34.6364 238.943 29.7273C238.943 26.0454 239.436 22.7348 240.42 19.7954C241.42 16.8409 242.83 14.3258 244.648 12.25C246.466 10.1742 248.617 8.58333 251.102 7.47727C253.587 6.37121 256.322 5.81818 259.307 5.81818C261.761 5.81818 264.049 6.18939 266.17 6.93181C268.307 7.65908 270.208 8.69696 271.875 10.0454C273.557 11.3788 274.958 12.9773 276.08 14.8409C277.201 16.6894 277.973 18.7424 278.398 21H272.58Z" stroke="white" stroke-width="10" mask="url(#path-1-outside-1_1_6)"/>
</svg>

    </div>
  )
}
export default Loading;


Enter fullscreen mode Exit fullscreen mode

Implementing the Loading Component to the App

  • Let's begin with importing the Loading.jsx into the App.js import Loading from "./Loading";
  • Now, since a loading screen only appears in the beginning of the render we will make use of React.useState() and React.useEffect()
  • Let's create a local state called loading initialized to true and use setLoading to toggle it's value.
  • Using useEffect()and setTimeout() to change the value of loading to false.
  • After that, we will check if loading is true we will return <Loading/>


import Loading from "./Loading";
import "./styles.css";
import { useEffect, useState } from "react";
export default function App() {
  const [loading, setLoading] = useState(true)
    useEffect(() => {
        setTimeout(() => setLoading(false), 3300)
    }, [])
    if (loading) {
        return <Loading/>
    }
  return (
    <div className="App">
      <h1>Hello</h1>
    </div>
  );
}



Enter fullscreen mode Exit fullscreen mode

Styling the Page

Let's begin by styling the App.js and then move on to the Loading component.

  • Styling the Main App ```

body{
margin:0;
padding: 0;
box-sizing: border-box;
}
.App {
font-family: sans-serif;
text-align: center;
}

- Styling the Loader
Now, we will be using the [`stroke-dasharray`](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-dasharray) and [`stroke-dashoffset`](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-dashoffset) property in CSS to animate our SVG. I highly advise learning about this property if you are not familiar with it. Basically, we will be playing the stroke of the individual child path of the SVG.


Enter fullscreen mode Exit fullscreen mode

loader-container{

max-width:220px;
position: absolute;
top:50%;
left: 50%;
transform: translate(-50%,-50%);
}

loader path:nth-child(2){

stroke-dasharray: 200%;
stroke-dashoffset: 200%;
animation: strokeAnimate 2s 0s ease forwards;
}

loader path:nth-child(3){

stroke-dasharray: 100%;
stroke-dashoffset: 100%;
animation: strokeAnimate 2s 0.3s ease forwards;
}

loader path:nth-child(4){

stroke-dasharray: 100%;
stroke-dashoffset: 100%;
animation: strokeAnimate 2s 0.9s ease forwards;
}

loader path:nth-child(5){

stroke-dasharray: 100%;
stroke-dashoffset: 100%;
animation: strokeAnimate 2s 1.2s ease forwards;
}

loader path:nth-child(6){

stroke-dasharray: 100%;
stroke-dashoffset: 100%;
animation: strokeAnimate 2s 1.5s ease forwards;
}

loader path:nth-child(7){

stroke-dasharray: 100%;
stroke-dashoffset: 100%;
animation: strokeAnimate 2s 1.8s ease forwards;
}

loader path:nth-child(8){

stroke-dasharray: 100%;
stroke-dashoffset: 100%;
animation: strokeAnimate 2s 2.1s ease forwards;
}

@keyframes strokeAnimate{
to{
stroke-dashoffset: 0;

}
}

@media screen and (max-width: 768px) {
#loader-container{
max-width:150px;
}
#loader{
width:150px;
}
}

@media screen and (max-width:650px) {
#loader-container{
max-width:100px;
}
#loader{
width:100px;
}
}

## Result



### Final Thoughts
I think this method is pretty slick and easy to create awesome Loading Screens. Do let me know if you have any doubts or facing any problem implementing this. 

Adios Amigo 👋

![Tuco](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t7oq5poteafrau61bkbt.png)

Enter fullscreen mode Exit fullscreen mode

Top comments (3)

Collapse
 
ricesucooker profile image
Top

This really is super helpful thank you so much!

Collapse
 
omarelmoez_54 profile image
Omar Elmoez

That's Great.
Thanks for sharing in such an organized form. 👍

Collapse
 
beginarjun profile image
Arjun Sharma

Thanks so much for appreciating it ❤