Building an Amazing Random Joke Generator with React

joke generator

In this tutorial, we’ll explore how to create a simple React application that fetches and displays random jokes using the JokeAPI. We’ll delve into the code, explaining each component, styling choice, and the overall structure of the application.

Overview:

We’ll cover the following key aspects of the Random Joke Generator:

  1. React Components:
    • We’ll break down the React components used in the application, including their states and lifecycle.
  2. API Integration:
    • Explore how the application fetches random jokes from the JokeAPI and updates the UI accordingly.
  3. Styling with CSS:
    • Understand the CSS styling choices for creating an aesthetically pleasing and responsive user interface.

React Components:

import React, { useState, useEffect } from "react";
import "./App.css";

const App = () => {
  const [joke, setJoke] = useState("");
  const [fade, setFade] = useState(false);
  const [loading, setLoading] = useState(true);

  // Fetch a random joke from the API
  const fetchJoke = async () => {
    const url =
      "https://v2.jokeapi.dev/joke/Any?blacklistFlags=nsfw,religious,political,racist,sexist,explicit&type=single";

    try {
      setLoading(true);
      const response = await fetch(url);
      const data = await response.json();
      setJoke(data.joke);
      setFade(true);
    } catch (error) {
      console.error("Error fetching joke:", error);
    } finally {
      setLoading(false);
    }
  };

  // Function to get a new random joke
  const getJoke = () => {
    setFade(false);
    fetchJoke();
  };

  // Fetch a joke on component mount
  useEffect(() => {
    fetchJoke();
  }, []);

  return (
    <div className="wrapper">
      <span role="img" aria-label="laughing emoji">
        😆
      </span>
      {loading ? (
        <div className="spinner"></div>
      ) : (
        <p className={fade ? "fade" : ""}>{joke}</p>
      )}
      <button onClick={getJoke} disabled={loading}>
        Get Random Joke
      </button>
    </div>
  );
};

export default App;
JSX
  • Explanation:
    • We use functional components and hooks (useState, useEffect) to manage the application state.
    • The fetchJoke function fetches a random joke from the JokeAPI, and the getJoke function triggers a new joke fetch.
    • The useEffect hook ensures that a joke is fetched when the component mounts.

API Integration:

// Fetch a random joke from the API
const fetchJoke = async () => {
  const url =
    "https://v2.jokeapi.dev/joke/Any?blacklistFlags=nsfw,religious,political,racist,sexist,explicit&type=single";

  try {
    setLoading(true);
    const response = await fetch(url);
    const data = await response.json();
    setJoke(data.joke);
    setFade(true);
  } catch (error) {
    console.error("Error fetching joke:", error);
  } finally {
    setLoading(false);
  }
};

// Fetch a joke on component mount
useEffect(() => {
  fetchJoke();
}, []);
JSX
  • Explanation:
    • The fetchJoke function uses fetch to request a random joke from the JokeAPI.
    • The API response is converted to JSON, and the joke is updated in the component state.
    • The loading state is managed to provide feedback while fetching.

CSS Styling:

@import url("https://fonts.googleapis.com/css2?family=Outfit:wght@500&display=swap");
* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
  font-family: "Outfit", sans-serif
}

body {
  background-color: #1e1c27;
}

.wrapper {
  width: 80vmin;
  padding: 50px 40px;
  background-color: #15161a;
  position: absolute;
  transform: translate(-50%, -50%);
  top: 50%;
  left: 50%;
  border-radius: 5px;
  box-shadow: 20px 20px 40px rgba(97, 63, 0, 0.4);
}

span {
  display: block;
  text-align: center;
  font-size: 100px;
}

p {
  font-size: 16px;
  color: #ffffff;
  font-weight: 400;
  text-align: center;
  word-wrap: break-word;
  line-height: 35px;
  margin: 30px 0;
  opacity: 0;
}

.fade {
  opacity: 1;
  transition: opacity 1.5s;
}

button {
  display: block;
  background-color: #fab22e;
  border: none;
  font-size: 18px;
  color: #171721;
  font-weight: 600;
  padding: 12px 25px;
  margin: 0 auto;
  border-radius: 5px;
  cursor: pointer;
  outline: none;
}
.spinner {
  border: 4px solid rgba(255, 255, 255, 0.3);
  border-radius: 50%;
  border-top: 4px solid #fab22e;
  width: 40px;
  height: 40px;
  animation: spin 1s linear infinite;
  margin: 30px auto;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}
CSS
  • Explanation:
    • The CSS styles define the overall look and feel of the application.
    • A custom font (“Outfit”) is imported for a unique typography style.
    • The color scheme and layout are designed to provide a visually appealing interface.
    • The spinner animation provides a loading indicator.

Detailed Explanation:

  1. React Components:
    • The App component is the main component managing state and rendering UI.
    • States (joke, fade, loading) control the joke content, fade animation, and loading spinner visibility.
    • The fetchJoke and getJoke functions manage API calls and state updates.
  2. API Integration:
    • The fetchJoke function fetches a single random joke from the JokeAPI using the fetch function.
    • The useEffect hook ensures that a joke is fetched when the component mounts.
    • Loading state manages the visibility of the spinner during API requests.
  3. CSS Styling:
    • The application has a dark-themed design for a modern and visually appealing look.
    • The wrapper has a fixed position in the center of the screen with a subtle box shadow.
    • Typography choices, color scheme, and layout contribute to a cohesive and pleasant user experience.
    • The fade-in animation adds a subtle transition when a new joke is displayed.

Conclusion:

By combining React, JavaScript, and CSS, we’ve built a simple Random Joke Generator app that fetches jokes from an API and presents them in a stylish interface. You can further enhance this app by adding features like category filters or sharing options.

Feel free to modify the code, experiment with styles, or extend functionality to make it your own.

Happy coding!

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

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