Creating Stunning Loading Screens in React: A Guide to Building 3 Types of Loading Screens
Hey Devs👋,
- Type-1 : Using react-loading library.
- Type-2 : Using react-lottie library.
- Type-3 : Using simple
CSS
.
This post will be the 3-part. If you prefer to watch video tutorial then you can watch it here else just watch first 2 minutes to get an idea of what we’re going to build here..and keep reading!😄
Before we start let’s create the React app by using following commands,
npx create-react-app react-loading-screen
Next, let’s install two libraries that we’re going to use.
npm install react-loading react-lottie
Type 1: Loading Screen with react-loading
Create separate file called PreLoader1.js
. Let’s create functional Component and here, we’re going to use two states,
const [data, setData] = useState([]);
const [done, setDone] = useState(undefined);
data state
: To store data which comes from API call.done state
: It is boolean to decide weather to show pre-loader or not.
Now in the useEffect
,
useEffect(() => {
setTimeout(() => {
fetch("https://jsonplaceholder.typicode.com/posts")
.then((response) => response.json())
.then((json) => {
console.log(json);
setData(json);
setDone(true);
});
}, 2000);
}, []);
Now in the above useEffect
method, first we use fetch method to get data from api then we convert that data into json
,
then we will set data
state with json
data, and after that set done
state to true
.
NOTE: Here, I have used time out function for 2 seconds so that we can see loading screen for more time. Now, remember if you don’t need controlled loading screen then you can alsways put the simple loading screen with some css on the index.html. So it will run until the
react-dom
takes control.
Now let’s render our component.
1import React, { useEffect, useState } from "react";
2import ReactLoading from "react-loading";
3
4function PreLoader1() {
5 const [data, setData] = useState([]);
6 const [done, setDone] = useState(undefined);
7
8 useEffect(() => {
9 setTimeout(() => {
10 fetch("https://jsonplaceholder.typicode.com/posts")
11 .then((response) => response.json())
12 .then((json) => {
13 console.log(json);
14 setData(json);
15 setDone(true);
16 });
17 }, 2000);
18 }, []);
19
20 return (
21 <>
22 {!done ? (
23 <ReactLoading
24 type={"bars"}
25 color={"#03fc4e"}
26 height={100}
27 width={100}
28 />
29 ) : (
30 <ul>
31 {data.map((post) => (
32 <li key={post.id}>{post.title}</li>
33 ))}
34 </ul>
35 )}
36 </>
37 );
38}
39
40export default PreLoader1;
41
Line 22: We will check if done
state is false then we will render pre-loading component else we will render data we want to show.
Line 23: Here, I have used react-loading library, where we only have to set type, color, height and width. you can find more functionalities on this url.
Line 30: From here I have mapped data state inside the ul tag which returns title of each post in li tag. (use console.log()
inside useEffect
to see what kind of data we are getting)
Let’s import this inside the App.js
file. Clean up everything from the App.js
file and import the PreLoader1
component as the following code block,
import React from "react";
import "./App.css"
import PreLoader1 from "PreLoader1.js";
function App() {
return (
<div className="App">
<PreLoader1 />
</div>
);
}
export default App;
In the App.css
file add the following styles,
*,*::before,*::after{
margin:0;
padding:0;
box-sizing: border-box;
}
body{
background-color:#1b1b1b;
}
.App{
width:100vw;
height:100vh;
display:flex;
justify-content:center;
align-items:center;
}
Type-2: Loading Screen with react-lottie
Let’s create new file and name it as PreLoader2.js
. create functional component, and import the react-Lottie
library.
import Lottie from "react-lottie";
In this type of loading screen we have to download animation files from lottie files. For this tutorial we will use the following two lottie animation files,
Download these files(Lottie JSON) and keep them in your project directory. Let’s import this json files like the following code block,
import * as location from "../79794-world-locations.json";
import * as success from "../1127-success.json";
As mentioned in the react-Lottie
library documentation, we need to set default options to use this animation files in our project so first declare this options as,
const defaultOptions1 = {
loop: true,
autoplay: true,
animationData: location.default,
rendererSettings: {
preserveAspectRatio: "xMidYMid slice",
},
};
const defaultOptions2 = {
loop: true,
autoplay: true,
animationData: success.default,
rendererSettings: {
preserveAspectRatio: "xMidYMid slice",
},
};
defaultOptions1
for first file while defaultOptions2
for the second file. In this component we’re going to use 3 state,
const [data, setData] = useState([]);
const [loading, setloading] = useState(undefined);
const [completed, setcompleted] = useState(undefined);
data state
: To store data which comes from API call.loading state
: Boolean state for first animation file.completed state
: Boolean state for second animation file when API call is completed. Now, let’s useuseEffect
method to set theses states.
useEffect(() => {
setTimeout(() => {
fetch("https://jsonplaceholder.typicode.com/posts")
.then((response) => response.json())
.then((json) => {
console.log(json);
setData(json);
setloading(true);
setTimeout(() => {
setcompleted(true);
}, 1000);
});
}, 2000);
}, []);
This useEffect
method is almost same as in the PreLoader1.js
,
only difference is that instead of done
state we have to set completed
and loading
state to true. Also, I have used one more timeout function for 1 sec to see the 2nd animation.
return (
<>
{!completed ? (
<>
{!loading ? (
<Lottie options={defaultOptions1} height={200} width={200} />
) : (
<Lottie options={defaultOptions2} height={100} width={100} />
)}
</>
) : (
<>
<h1>Your Data</h1>
</>
)}
</>
);
}
As shown in the above code, in the return, if completed
state is false then we will render loading screen else we will render our data. In the animation part we will do one more conditional rendering, when loading
state is false then we will render the earth animation else we will render the success animation. Dont’t forget to set options={defaultOptions1}
for file 1 and options={defaultOptions2}
for file 2.
Full Code:
1import React, { useEffect, useState } from "react";
2import Lottie from "react-lottie";
3
4import * as location from "../1055-world-locations.json";
5import * as success from "../1127-success.json";
6
7const defaultOptions1 = {
8 loop: true,
9 autoplay: true,
10 animationData: location.default,
11 rendererSettings: {
12 preserveAspectRatio: "xMidYMid slice",
13 },
14};
15
16const defaultOptions2 = {
17 loop: true,
18 autoplay: true,
19 animationData: success.default,
20 rendererSettings: {
21 preserveAspectRatio: "xMidYMid slice",
22 },
23};
24
25function PreLoader2() {
26 const [data, setData] = useState([]);
27 const [loading, setloading] = useState(undefined);
28 const [completed, setcompleted] = useState(undefined);
29
30 useEffect(() => {
31 setTimeout(() => {
32 fetch("https://jsonplaceholder.typicode.com/posts")
33 .then((response) => response.json())
34 .then((json) => {
35 console.log(json);
36 setData(json);
37 setloading(true);
38
39 setTimeout(() => {
40 setcompleted(true);
41 }, 1000);
42 });
43 }, 2000);
44 }, []);
45
46 return (
47 <>
48 {!completed ? (
49 <>
50 {!loading ? (
51 <Lottie options={defaultOptions1} height={200} width={200} />
52 ) : (
53 <Lottie options={defaultOptions2} height={100} width={100} />
54 )}
55 </>
56 ) : (
57 <>
58 <h1>Your Data</h1>
59 <br />
60 <h6 style={{ position: "Absolute", right: "5rem", bottom: "0" }}>
61 <a
62 style={{ color: "white" }}
63 href="https://lottiefiles.com/ijum4kzkmt"
64 >
65 Earth Animation by Hanina Kahfi on LottieFiles
66 </a>
67 <br />
68 <a style={{ color: "white" }} href="https://lottiefiles.com/darius">
69 Success Animation by Chris Gannon on LottieFiles
70 </a>
71 </h6>
72 </>
73 )}
74 </>
75 );
76}
77
78export default PreLoader2;
79
Now as per the Creative Commons License of Lottie files, The creator(s) must be attributed in your application. You can attribute creator as shown in line no 60 to 71.
Type-3: Custom Built Loading Screen with CSS
In this type of loading screen we are not going to use any library instead we are only using simple css styling. Now the logic of displaying pre-loader is same as in the type-2 so here I’m not going to show you the whole process. Let’s create new file PreLoader3.js
and copy the whole code from PreLoader2.js
file and remove all code related with react-Lottie
library and keep everything as it is.
only change return statement as shown below,
return (
<>
{!completed ? (
<>
{!loading ? (
<div className="spinner">
<span>Loading...</span>
<div className="half-spinner"></div>
</div>
) : (
<div className="completed">✓</div>
)}
</>
) : (
<>
<h1>Your Data</h1>
</>
)}
</>
);
In the above code, div
with the class spinner
contains Loading text and spinner. while div
with the className
completed contains success symbol.(✓). Now let’s do some css styling. Create separate file preloader3.css
for styling and import it in the Preloader3.js
file.
.spinner {
width: 300px;
height: 300px;
display: flex;
justify-content: center;
align-items: center;
background-color: transparent;
}
.spinner span {
font-size: 2rem;
animation: fade 1s linear 0s infinite;
padding-right: 1rem;
}
.half-spinner {
width: 50px;
height: 50px;
border: 3px solid #03fc4e;
border-top: 3px solid transparent;
border-radius: 50%;
animation: spin 0.5s linear 0s infinite;
}
.completed {
font-size: 2rem;
color: #03fc4e;
animation: bigger 1s linear;
}
@keyframes bigger {
from {
transform: scale(0);
}
to {
transform: scale(2);
}
}
@keyframes spin {
from {
transform: rotate(0);
}
to {
transform: rotate(360deg);
}
}
@keyframes fade {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
Here, .spinner
class is simply box for spinner. .spinner span
contains styling and animation for loading text. .half-spinner
contains styling for spinner. Now to cut this whole spinner as in line no 20 you just have to set border top to transparent. .completed
contains styling and animation for success(✓) symbol.
This is the End of this article🏆, I hope you liked it.