Hi! Developers welcome to this article. When a user clicks on a button on a website, they expect a response. When you click a button and there's no immediate response, users might wonder if anything is happening. During this time, many users click the button multiple times, which causes unnecessary load on the backend. To overcome these problems we can use a loading spinner. When the user clicks the button a spinner will appear, letting the user understand that the process is in progress.
In this article, you will learn how to add a loading spinner to a button in a ReactJS application. We'll make a button that fetches data. When loading, the spinner shows up, and the button is disabled. Once data is loaded, the spinner vanishes, and the button goes back to normal.
Ready? Let's get started!
- Step 1: Set Up Your React Application
- Step 2: Create the ButtonWithSpinner Component
- Step 3: Add CSS for the Spinner and Button
- Step 4: Integrate the Component into Your App
- Step 5: Set Up the Entry Point
- Step 6: Run Your Application
Step 1: Set Up Your React Application
First, ensure you have a React application set up. If not, you can create one using Create React App:
npx create-react-app my-app
cd my-app
Step 2: Create the ButtonWithSpinner Component
Next, create a new component named ButtonWithSpinner.jsx to handle the API data response and display the loading spinner.
// src/ButtonWithSpinner.jsx
import React, { useState } from 'react';
import './App.css';
const ButtonWithSpinner = () => {
const [loading, setLoading] = useState(false);
const [data, setData] = useState(null);
const [error, setError] = useState(null);
const handleSubmit = async (event) => {
event.preventDefault();
setLoading(true);
setError(null);
setData(null);
try {
const response = await fetch('https://randomuser.me/api/');
if (!response.ok) {
throw new Error('Network response was not ok');
}
const result = await response.json();
setData(result);
} catch (error) {
setError(error.message);
} finally {
setLoading(false);
}
};
return (
<div className="container">
<form onSubmit={handleSubmit}>
<button type="submit" disabled={loading}>
{loading ? <div className="spinner"></div> : 'Fetch Data'}
</button>
</form>
{error && <div className="error-message">Error: {error}</div>}
{data && (
<div className="data-display">
<h3>Fetched Data:</h3>
<pre>{JSON.stringify(data, null, 2)}</pre>
</div>
)}
</div>
);
};
export default ButtonWithSpinner;
We handle state using React's useState hook, managing loading, data, and errors.
When the button is clicked, it triggers the handleSubmit function. This function sets loading to true, clears errors and data, and fetches from the API.
We fetch data from random API. If successful, data is stored; if not, error is stored.
During loading, the button displays a spinner. Afterward, fetched data or error message appears below the button.
Step 3: Add CSS for the Spinner and Button
Create a CSS file named App.css to style the button and spinner.
/* src/App.css */
.container {
display: flex;
flex-direction: column;
align-items: center;
}
h1 {
text-align: center;
}
form {
margin-bottom: 20px;
}
button {
background: linear-gradient(135deg, #ff6f61, #d62a78);
color: white;
border: none;
padding: 10px 20px;
font-size: 16px;
font-weight: bold;
cursor: pointer;
border-radius: 50px;
transition: all 0.3s ease, box-shadow 0.3s ease;
}
button:disabled {
background: linear-gradient(135deg, #ff6f61a6, #d62a78a6);
cursor: not-allowed;
}
button:hover:not(:disabled) {
box-shadow: 0px 4px 15px rgba(0, 0, 0, 0.2);
}
.spinner {
border: 3px solid rgba(255, 255, 255, 0.3);
border-top-color: #fff;
border-radius: 50%;
width: 16px;
height: 16px;
animation: spin 0.6s linear infinite;
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.error-message {
color: red;
margin-top: 10px;
}
.data-display {
background-color: #f0f0f0;
padding: 20px;
width: 100%;
max-width: 600px;
}
.data-display h3 {
margin-top: 0;
}
Step 4: Integrate the Component into Your App
Ensure your App.js is set up to use the ButtonWithSpinner component.
// src/App.js
import React from 'react';
import ButtonWithSpinner from './ButtonWithSpinner';
import './App.css';
const App = () => {
return (
<div className="App">
<h1>Fetch Random Data with Loading Button</h1>
<ButtonWithSpinner />
</div>
);
};
export default App;
The main component of your application includes the ButtonWithSpinner component and a header.
Step 5: Set Up the Entry Point
Make sure your index.js is correctly set up to render the App component.
// src/index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
ReactDOM.createRoot(document.getElementById("root")).render(
<>
<App />
</>
);
Step 6: Runn Your Application
Run your application using the following command:
npm start
Navigate to localhost 3000 in your browser. You can see a "Fetch Data" button. When you click it, the loading spinner will appear until the data is fetched from the API, and then the fetched data will be displayed.
Conclusion
You can integrate the loading spinner on various buttons like submit, copy, or redirect buttons on your website. Wherever there's a need to display data after a button click, implementing this feature can make your website more appealing and keep users engaged. So, if the user clicks on any button, they'll feel assured knowing that the data will load soon, keeping them on your site and making their experience enjoyable.
Important: When you have to load the whole page or a big part of it, using a loading spinner is seen as old-fashioned. It's better to use skeleton animation instead.
If you have any questions about this article or related to web development, you can ask them in the question box given below, and you will get the answer as soon as possible.