Building a Bit of Humor: Fetching a Joke with React and a JokeAPI
Manish Tamang / December 22, 2024
5 min read • NaN views
Building a Bit of Humor: Fetching a Joke with React and an API
In the world of web development, sometimes it's fun to add a bit of personality and levity to your site. This post will explore how I added a simple "Random Programming Joke" card to my portfolio website using React and the Joke API. This seemingly minor feature involves concepts like API consumption, state management in React, and handling asynchronous operations.
The Core: JokeCard.tsx
The heart of this feature lies within the components/JokeCard.tsx
file:
import React, { useEffect, useState } from "react";const JokeCard = () => { const [joke, setJoke] = useState<string | null>(null); const [error, setError] = useState<string | null>(null); useEffect(() => { const fetchJoke = async () => { try { const response = await fetch( "https://v2.jokeapi.dev/joke/Programming?format=json" ); if (!response.ok) { throw new Error("Failed to fetch joke"); } const data = await response.json(); setJoke(data.joke || `${data.setup} - ${data.delivery}`); setError(null); } catch (error) { console.error("Error fetching joke:", error); setJoke(null); setError("Oops! Something went wrong. Please try again."); } }; fetchJoke(); }, []); return ( <article className="rounded-xl border-2 border-gray-100 bg-white dark:border-gray-800 dark:bg-gray-900"> <div className="flex items-start gap-4 p-4 sm:p-6 lg:p-8"> <div> <h3 className="font-medium sm:text-lg text-gray-900 dark:text-gray-100"> <a href="https://jokeapi.dev/" className="hover:underline"> Random Programming Joke </a> </h3> <p className="text-sm text-gray-700 dark:text-gray-300"> {error ? error : joke || "Loading joke..."} </p> <div className="mt-2 sm:flex sm:items-center sm:gap-2"> <p className="hidden sm:block sm:text-xs text-gray-500 dark:text-gray-400"> Joke API </p> </div> </div> </div> </article> );};export default JokeCard;
Let's break this down step-by-step:
- Import Statements
import React, { useEffect, useState } from 'react';
- This line imports the necessary React hooks:
useEffect
(for side effects like API calls) anduseState
(for managing the component's state)
- This line imports the necessary React hooks:
- Component Definition
const JokeCard = () => { ... }
- This is a functional component called
JokeCard
- This is a functional component called
- State Management
const [joke, setJoke] = useState<string | null>(null);
- The
joke
state variable will hold the joke text as a string. We initialize it tonull
to indicate that we don't have a joke yet.
- The
const [error, setError] = useState<string | null>(null);
- The
error
state variable holds error message, set tonull
initially.
- The
useEffect
HookuseEffect(() => { ... }, []);
- The
useEffect
hook is used here to trigger the API call once after the component mounts ([]
empty dependency array).
- The
fetchJoke
Functionconst fetchJoke = async () => { ... }
- This function is declared as async because it involves asynchronous operations like fetching data.
- Fetching Data:
const response = await fetch('https://v2.jokeapi.dev/joke/ Programming?format=json');
- We use JavaScript's built-in
fetch
to make aGET
request to the Joke API. The URL here is specifically requesting a "Programming" category joke in JSON format.
- We use JavaScript's built-in
- Error Handling:
if (!response.ok) { throw new Error('Failed to fetch joke'); }
- We check if the response was successful using
response.ok
. If not, we throw a new error, which will jump to thecatch
block.
- We check if the response was successful using
- Parsing JSON:
const data = await response.json();
- If the response is successful, we parse the JSON data from the response body.
- Setting State:
setJoke(data.joke || '${data.setup} - ${data.delivery}');
- The API returns jokes in two formats: as a single
joke
string, or with asetup
anddelivery
. Ifdata.joke
exists, we use that; otherwise, we construct the joke string from setup and delivery.
- The API returns jokes in two formats: as a single
setError(null)
: if the API call is successful, the value of the error state will be null. URL), we set thejoke
state tonull
and update theerror
state.
- JSX Rendering
How It All Comes Together
- Initial Render: When the component mounts, the
useEffect
hook triggers thefetchJoke
function to get data from the API - Data Fetching: The fetch method is used to send a request to the specified URL and gets data from the API.
- State Updates: The fetched data is used to update the state variable, causing the component to re-render and display the joke.
- Error Handling: If anything goes wrong, the
error
state gets updated which will display the error message, such as "Failed to fetch joke" or "Something went wrong. Please try again" - UI Display: The UI will then display the joke inside a card component or a "Loading..." message while the data is being fetched.
Key Takeaways
- Asynchronous Operations: API calls are asynchronous, meaning they take time to complete. We use
async/await
to handle them elegantly. useState
Hook: This hook is fundamental for creating interactive interfaces, enabling the component to update and re-render as the joke data changes.useEffect
Hook:useEffect
helps us perform side-effects after render such as API calls. The empty array in dependency makes sure that it is called only once.- Error Handling: It's essential to handle potential errors when fetching data from external APIs, ensuring a better user experience.
- UI: The UI is responsive so that the user can easily view the Joke Card.
Integration
To integrate this component into your homepage, you would simply import and use it within your main page component (pages/index.tsx
):
import JokeCard from "components/JokeCard";export default function Home() { return ( <div> <JokeCard /> </div> );}
Conclusion
Fetching and displaying data from an API might seem complex, but it can be broken down into smaller, more understandable parts, as we've seen here. This approach demonstrates how to handle asynchronous operations and state updates in a React component, all while adding a small piece of fun to the website. The JokeCard
component makes use of the Joke API and provides a light-hearted addition to the website, while also showcasing real-world application of React and API handling techniques.
This structure provides a foundation for handling other dynamic content on your website, allowing you to connect to all types of APIs and create compelling user experiences!