If you're looking to enhance your React skills by building simple projects, a Quote Generator is an ideal choice. In this guide, we’ll create a Quote Generator that fetches random advice from an external API using React, axios
, and a loading state to enhance the user experience. This project will help you get hands-on practice with state management, conditional rendering, and API handling in React.
Project Overview
This Quote Generator will display random pieces of advice by fetching data from the Advice Slip API. Upon clicking a button, a new piece of advice will be displayed, with a loading indicator showing while the advice is being fetched.
Prerequisites
Before we dive into the code, ensure you have the following:
- Basic knowledge of React, including hooks like
useState
. - Familiarity with axios for API requests.
- Node.js and npm installed.
Step 1: Set Up Your React Project
First, create a new React project by running the following command in your terminal:
npx create-react-app quote-generator
Once the setup is complete, navigate to the project folder:
cd quote-generator
Install axios
, which we'll use to fetch data from the API:
npm install axios
Step 2: Update App.js
Replace the default content in src/App.js
with the following code:
import { useState } from "react";
import "./App.css";
import axios from "axios";
const apiUrl = "https://api.adviceslip.com/advice";
function App() {
const [advice, setAdvice] = useState(
"Please click button to see your advice !!"
);
const [isLoading, setIsLoading] = useState(false);
const handleQuoteGenerate = async () => {
setIsLoading(true);
const response = await axios.get(apiUrl);
setAdvice(response.data.slip.advice);
setIsLoading(false);
// console.log(response.data);
};
return (
<div className="App">
<h1> Quote Generator </h1>
<section className="quote-container">
{isLoading ? (
<p className="quote">...</p>
) : (
<blockquote className="quote">{advice}</blockquote>
)}
</section>
<button className="default-btn" onClick={handleQuoteGenerate}>
Give Me Advice
</button>
</div>
);
}
export default App;
Code Explanation
-
State Management:
- We define two states using the
useState
hook:-
advice
: This holds the current piece of advice, initialized with a default message ("Please click button to see your advice!!"). -
isLoading
: This is a boolean flag that manages the loading state, initially set tofalse
.
-
- We define two states using the
-
API Call:
- The
handleQuoteGenerate
function is an asynchronous function that fetches advice from the Advice Slip API. - Before the request is made, we set
isLoading
totrue
to display the loading indicator. After the API request completes, the fetched advice is set in theadvice
state, andisLoading
is set back tofalse
.
- The
-
Conditional Rendering:
- We use a ternary operator to conditionally render the loading indicator (
...
) whenisLoading
istrue
. Once the advice is fetched andisLoading
isfalse
, the<blockquote>
tag displays the fetched advice.
- We use a ternary operator to conditionally render the loading indicator (
-
Button:
- The "Give Me Advice" button triggers the
handleQuoteGenerate
function, fetching a new piece of advice every time it's clicked.
- The "Give Me Advice" button triggers the
Step 3: Add Some Basic Styling
To improve the visual appearance of the app, let's add some simple styles. In the src/App.css
& src/index.css
file, add the following CSS:
/* src/App.css */
.App {
text-align: center;
}
.quote-container {
border: 1px solid #f5f5f5;
border-radius: 8px;
margin-bottom: 20px;
padding: 20px;
width: 650px;
background: linear-gradient(
150deg,
#2b2e4a,
#3e345e,
#57386e,
#723b78,
#903c7a,
#af3d73,
#cd3f63,
#e84545
);
}
.quote {
font-weight: bold;
font-size: 20px;
color: white;
}
.default-btn {
padding: 10px 20px;
border-radius: 8px;
border: 0;
background-color: #2b2e4a;
color: white;
font-weight: bold;
font-size: 18px;
cursor: pointer;
transition: all 0.3s;
}
.default-btn:hover {
background-color: #3e345e;
}
Now, add in src/index.css
/* src/index.css */
html,
body {
height: 100%;
}
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
"Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
display: flex;
justify-content: center;
align-items: center;
background: linear-gradient(
135deg,
#ffe5ce,
#ffd0ba,
#ffb9b0,
#ffa2b0,
#fd8dba,
#ec7cca,
#cd72de,
#9c71f2
); /* made at https://learnui.design/tools/gradient-generator.html */
}
Step 4: Run the Application
Once you've added the code and styles, run your application with:
npm start
This will launch the app in your browser, where you’ll see a heading, the default advice message, and the button. Click the button to fetch a new piece of advice from the API.
Features of the App
- API Integration: The app integrates with the Advice Slip API to fetch random advice.
-
Loading Indicator: A simple loading indicator (
...
) is shown while waiting for the advice to load. - User Interaction: The user can click the button multiple times to fetch new pieces of advice.
Potential Enhancements
Once you're comfortable with this basic version of the quote generator, you can extend it with additional features:
- Error Handling: Implement error handling for cases when the API fails to respond.
try {
const response = await axios.get(apiUrl);
setAdvice(response.data.slip.advice);
} catch (error) {
setAdvice('Oops! Something went wrong.');
} finally {
setIsLoading(false);
}
-
Save Favorite Quotes: Allow users to save their favorite quotes using
localStorage
. - Sharing: Add a feature to allow users to share their favorite advice on social media.
Conclusion
Building this simple Quote Generator in React is an excellent project for beginners. It allows you to get hands-on experience with axios
for API requests, React’s useState
for managing state, and useEffect
for handling side effects like fetching data. Plus, it’s a fun and interactive app that can be easily extended with new features as your React skills grow!
Checkout other projects as well
Top comments (0)