How to Make Quote Generator in React

In this article, we are going to make a quote generator in React. We will use a JSON file to get a random quote, this will allow our application to get a unique and new quote every time we refresh the application. In this application, we will add a let’s say textarea and a button to refresh the quote.

This project won’t be too hard to do, but it will be very simple and easy to do. So let’s make this application step-by-step.

Pre-requisites to Make Quote Generator in React

  • Basic knowledge of ReactJS.
  • Basic knowledge of CSS.
  • Basic knowledge of React props and hooks.

Customizing App Component

Firstly, we will make some changes in the App.js component. Here we have added our Quote component, in which we will add our main logic. Then we imported the App.css file, in which we will have some basic style of course. And lastly, we have just called <Quotes> in here to access Quote.js. As we can see, our App.js file is pretty straightforward and clean, this is the power of react components. We will add logic in our Quote.js file, so let’s move to it.

import React from 'react';
import Quotes from './components/Quotes';
import './App.css';

function App() {
  return (
    <div className="App">
      <Quotes />
    </div>
  );
}

export default App;

Adding Required Modules

Now in the Quote.js component, we will add some modules that are required to implement this project. Here we have added React, and useState to change the quote every time, and we are using the useEffect hook so that we can load our quote as soon as the application gets printed on DOM. Then we added 2 SVG files to add a Twitter icon and a Tumblr icon.

import React, { useState, useEffect } from 'react';

import twitterIcon from '../twitter.svg';
import tumblrIcon from '../tumblr.svg';

Creating Base Structure For Application

Now, after adding modules, we will make the basic structure for the application. Here we have added a <div> for the quote box, in which we have added another div for text and author. Now we have added a <div> for buttons, in this we have added a Twitter icon and a Tumblr icon. Lastly, we have added a button to change the current quote, with an event listener to listen click event, in which we have passed a function named handleClick.

Remember, this is not a complete version of this structure, its values will be changed as we move forward in this project.

return (
    <div id="quote-box">
      <div id="text"><p>quote</p></div>
      <div id="author"><p>author</p></div>

      <div id="buttons">
        <div className="social-media">
          <a href="#" id="twet-quote">
            <span><img src={twitterIcon} alt="" /></span>
          </a>
          <a href="#" id="tumlr-quote">
            <span><img src={tumblrIcon} alt="" /></span>
          </a>
        </div>
        <button onClick={handleClick} id="new-quote">New Quote</button>
      </div>
    </div>
  )
}
Quote Generator in React

Adding States

Now we need to add the states, one for quote and another for author. Since quote and author are going to change as we know so that we have created states for quote and author.

const [quote, setQuote] = useState('');
  const [author, setAuthor] = useState('');

Generating The Random Quote

Now we need to generate quotes which is our main logic, here we have added a function getQuote, in this, we have declared a variable named “url” with the link of our JSON file. So we have selected this link in which we have some Quotes in there. Now we have used fetch(url).then(res => res.json()) to fetch and get the data from JSON files. Then to fetch data from this we have added a variable with data.quotes value, so basically in this variable we have stored a list of objects in which we have a quote and author name.

After that, we have applied Math.floor(Math.random() * dataQuotes.length) to get a random number that ranges the maximum length of the dataQuotes’s length. And we this value we will pass in the index number of dataQuotes to get that numbered quote using this line of code let randomQuote = dataQuotes[randomNum];. As we know dataQuotes is an array of quotes and randomNum is an index value of this array.

Lastly, we will change the value of these states with the obtained quote and author. Now for the handleClick() function, we will call this getQuote() function to generate a random quote again, similarly, we will call this function in useEffect, so that we can get our first quote as we load the application.

Lastly, we just have to change the value of the paragraph with states.

useEffect(() => {
    getQuote()
  }, []);

  const getQuote = () => {
    let url = `https://gist.githubusercontent.com/camperbot/5a022b72e96c4c9585c32bf6a75f62d9/raw/e3c6895ce42069f0ee7e991229064f167fe8ccdc/quotes.json`;
    fetch(url)
      .then(res => res.json())
      .then(data => {
        let dataQuotes = data.quotes;
        let randomNum = Math.floor(Math.random() * dataQuotes.length);
        let randomQuote = dataQuotes[randomNum];

        setQuote(randomQuote.quote);
        setAuthor(randomQuote.author);
      })
  }

   const handleClick = () => {
    getQuote();
   }

 return (
    <div id="quote-box">
      <div id="text"><p>{quote}</p></div>
      <div id="author"><p>{author}</p></div>

      <div id="buttons">
        <div className="social-media">
          <a href="#" id="twet-quote">
            <span><img src={twitterIcon} alt="" /></span>
          </a>
          <a href="#" id="tumlr-quote">
            <span><img src={tumblrIcon} alt="" /></span>
          </a>
        </div>
        <button onClick={handleClick} id="new-quote">New Quote</button>
      </div>
    </div>
  )
Quote Generator in React

Customization of The App

We have mainly focused on the React code, so we don’t get into the CSS part in deep. In the CSS part, we just have added some basic styles to the app, which purely depends on you to customize it. You can add the below CSS to your project if you don’t want to add much more things.

@import url('https://fonts.googleapis.com/css?family=Nunito&display=swap');

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  font-family: 'Nunito', sans-serif;
  background: #0059ff;
}

#quote-box {
  background: #fff;
  width: 40rem;
  margin: 10rem auto;
  padding: 3rem;
  border-radius: 5px;
}

#text {
  font-size: 2rem;
  margin-bottom: 1.5rem;
}

#author {
  display: flex;
  justify-content: flex-end;
  font-size: 1.2rem;
}

#buttons {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 2rem;
}

.social-media {
  display: flex;
}

.social-media > a {
  margin-right: .5rem;
  background: #0059ff;
  padding: .3rem .5rem;
  cursor: pointer;
  border-radius: 3px;
}

.social-media > a:hover {
  opacity: .9;
}

.social-media > a img {
  width: 1.5rem;
}

#new-quote {
  background: #0059ff;
  border: none;
  color: #fff;
  padding: .7rem 1rem;
  font-size: .9rem;
  font-weight: bold;
  border-radius: 2px;
  outline: none;
  cursor: pointer;
}

#new-quote:hover {
  opacity: 0.9;
}

Full Source Code to Make Quote Generator in React

index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

App.js

import React from 'react';
import Quotes from './components/Quotes';
import './App.css';

function App() {
  return (
    <div className="App">
      <Quotes />
    </div>
  );
}

export default App;

Quotes.js

import React, { useState, useEffect } from 'react';

import twitterIcon from '../twitter.svg';
import tumblrIcon from '../tumblr.svg';

const Quotes = () => {
  const [quote, setQuote] = useState('');
  const [author, setAuthor] = useState('');

  useEffect(() => {
    getQuote()
  }, []);

  const getQuote = () => {
    let url = `https://gist.githubusercontent.com/camperbot/5a022b72e96c4c9585c32bf6a75f62d9/raw/e3c6895ce42069f0ee7e991229064f167fe8ccdc/quotes.json`;
    fetch(url)
      .then(res => res.json())
      .then(data => {
        let dataQuotes = data.quotes;
        console.log(dataQuotes);
        let randomNum = Math.floor(Math.random() * dataQuotes.length);
        let randomQuote = dataQuotes[randomNum];

        setQuote(randomQuote.quote);
        setAuthor(randomQuote.author);
      })
  }

   const handleClick = () => {
    getQuote();
   }

  return (
    <div id="quote-box">
      <div id="text"><p>{quote}</p></div>
      <div id="author"><p>{author}</p></div>

      <div id="buttons">
        <div className="social-media">
          <a href="#" id="twet-quote">
            <span><img src={twitterIcon} alt="" /></span>
          </a>
          <a href="#" id="tumlr-quote">
            <span><img src={tumblrIcon} alt="" /></span>
          </a>
        </div>
        <button onClick={handleClick} id="new-quote">New Quote</button>
      </div>
    </div>
  )
}

export default Quotes;

App.css

@import url('https://fonts.googleapis.com/css?family=Nunito&display=swap');

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  font-family: 'Nunito', sans-serif;
  background: #0059ff;
}

#quote-box {
  background: #fff;
  width: 40rem;
  margin: 10rem auto;
  padding: 3rem;
  border-radius: 5px;
}

#text {
  font-size: 2rem;
  margin-bottom: 1.5rem;
}

#author {
  display: flex;
  justify-content: flex-end;
  font-size: 1.2rem;
}

#buttons {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 2rem;
}

.social-media {
  display: flex;
}

.social-media > a {
  margin-right: .5rem;
  background: #0059ff;
  padding: .3rem .5rem;
  cursor: pointer;
  border-radius: 3px;
}

.social-media > a:hover {
  opacity: .9;
}

.social-media > a img {
  width: 1.5rem;
}

#new-quote {
  background: #0059ff;
  border: none;
  color: #fff;
  padding: .7rem 1rem;
  font-size: .9rem;
  font-weight: bold;
  border-radius: 2px;
  outline: none;
  cursor: pointer;
}

#new-quote:hover {
  opacity: 0.9;
}

Output

Quote Generator in React

Check out the video reference here:

You may also like:

Reactjs Guru
Reactjs Guru

Welcome to React Guru, your ultimate destination for all things React.js! Whether you're a beginner taking your first steps or an experienced developer seeking advanced insights.

React tips & tutorials delivered to your inbox

Don't miss out on the latest insights, tutorials, and updates from the world of ReactJs! Our newsletter delivers valuable content directly to your inbox, keeping you informed and inspired.

13 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

Table of Contents