How to Easily Fetch and Display JSON in React

How to Easily Fetch and Display JSON in React

Using custom hooks
Ferenc Almasi β€’ Last updated 2024 February 02 β€’ Read time 10 min read β€’ React v18.2
Learn how you can easily fetch and display JSON data in your React application using custom hooks.
  • twitter
  • facebook
React Previous Tutorial

Working with remote JSON APIs is the most common way to consume dynamic data in a frontend application. In React, fetching and displaying JSON data can be done with the use of hooks.

In this tutorial, we will take a look at how to consume an API response using built-in and custom hooks, and how to display the retrieved data to the end-user in a meaningful way.


The JSON Endpoint

For this tutorial, we are going to use JSON Placeholder, a free fake REST API, to demonstrate how you can pull JSON data inside your React application. JSON Placeholder exposes a /users endpoint that we can use to grab fake user data and populate a table.

Copied to clipboard!
[
  {
    "id": 1,
    "name": "Leanne Graham",
    "username": "Bret",
    "email": "[email protected]",
    "address": { ... },
    "phone": "1-770-736-8031 x56442",
    "website": "hildegard.org",
    "company": { ... }
  },
  { ... }
]
users.json
Example response from JSON Placeholder

Fetching JSON in React Without Custom Hooks

First, let's see how you can fetch data in a component without using any custom hooks. This way, you can better understand the concept of how the cleaned-up version (using custom hooks) will work.

Before we start fetching, we need to wait for the component to mount. We can do this using a useEffect hook. This is where we want to fetch the JSON using the Fetch API in the following way:

Copied to clipboard! Playground
import { useEffect, useState } from 'react'

const endpoint = 'https://jsonplaceholder.typicode.com/users'

const App = () => {
    const [users, setUsers] = useState([])

    useEffect(() => {
        (async () => {
            const data = await fetch(endpoint)
                .then(res => res.json())

            setUsers(data)
        })()
    }, [])

    return (...)
}

export default App
App.js
Fetching data in React using a useEffect

Let's break down what this code snippet does:

  • Line 3: We store the JSON endpoint in a variable. In a real-world application, this is usually stored in a configuration file.
  • Line 6: To store this data in React, we want to use the useState hook.
  • Lines 8-15: The highlighted lines are responsible for fetching the data from the JSON endpoint. As useEffect cannot be an async function, an IIFE is used inside it to use async/await.
  • Line 13: Once the data is returned, we can use the setUsers updater function from our useState hook to expose the fetched users to our component.
  • Line 15: Don't forget to pass an empty array as the second parameter to the useEffect hook to tell React it should be executed during the mounting phase.
Looking to improve your skills? Check out our interactive course to master React from start to finish.
Master Reactinfo Remove ads

Fetching JSON in React With Custom Hooks

The above example works perfectly; however, we can improve upon it. If you need to fetch data in React in multiple components, it's better to extract this logic into a custom hook that can be reused throughout the application.

This way, you will end up with less code duplication and cleaner components. To outsource the above code into a custom hook, create a new file next to your component called useFetch and add the following:

Copied to clipboard! Playground
import { useState, useEffect } from 'react'

const useFetch = url => {
    const [state, setState] = useState([null, false])

    useEffect(() => {
        setState([null, true]);

        (async () => {
            const data = await fetch(url)
                .then(res => res.json())

            setState([data.body, false])
        })()
    }, [url])

    return state
};

export default useFetch
useFetch.js
Create the above custom hook in your codebase

This hook is responsible for doing the same thing as before, but now it is configurable through a parameter. To return the correct data, it uses the useState hook internally. Notice that the state is set to an array with two items on line 4:

  • null: The initial state for the data that will be returned from the custom hook.
  • false: The initial state for a loading indicator that is set to true as soon as we start the fetch. It is set back to false as soon as the data arrives.

Pass url to the dependency array to rerun the hook if the prop changes.

To use this hook inside the previous component, replace the useState and useEffect hooks with the following code:

Copied to clipboard! Playground
const App = () => {
    const [users, loading] = useFetch(endpoint)

    if (loading) {
        return <h1>Loading...</h1>
    }

    if (!users?.length) {
        return <h1>There are no users to be displayed πŸ€•</h1>
    }

    return (...)
}
App.js
Using the useFetch hook inside a component

We end up with a much cleaner and more declarative component. Thanks to the loading indicator, we can also display different states when we are waiting for the data to arrive. The users variable will hold the list of users. Don't forget to safeguard line:8 with optional chaining, as its initial value will be null.

πŸ” Login to get access to the full source code in one piece. With TypeScript types included.

Display the JSON

The only thing left for us to do is to actually display the JSON inside the component. To do this, we can make use of the map array method from JavaScript. Create the following table inside the component to display the users:

Copied to clipboard! Playground
return (
    <table>
        <thead>
            <tr>
                <th>ID</th>
                <th>Name (Username)</th>
                <th>Email</th>
                <th>Phone</th>
                <th>Website</th>
            </tr>
        </thead>
        <tbody>
            {users.map(user => (
                <tr key={user.id}>
                    <td>{user.id}</td>
                    <td>{user.name} ({user.username})</td>
                    <td>
                        <a href={`mailto:${user.email}`}>
                            {user.email}
                        </a>
                    </td>
                    <td>{user.phone}</td>
                    <td>
                        <a href={`https://${user.website}`} target="_blank">
                            {user.website}
                        </a>
                    </td>
                </tr>
            ))}
        </tbody>
    </table>
)
App.js
Displaying the JSON data

The important part is highlighted in the above code example. users is an array that we can loop over using the map array method. Each row must be decorated with a key property to let React identify and keep track of elements correctly.

Here, we can display properties one by one using td elements. To make email addresses responsive in HTML, we can use the mailto: prefix, followed by the email. This will launch the default mailer of the user when the link is clicked, with the recipient already filled in.


Display Pretty Printed JSON

Alternatively, for testing purposes, we can also dump the entire JSON object in a pretty formatted way using JSON.stringify, wrapped into a pre tag:

Copied to clipboard!
return (
    <pre>{JSON.stringify(users, null, 4)}</pre>
)
App.js
Pretty print JSON in React

The reason we need to use a pre tag is because pre tags have their white-space attribute set to pre which preserves whitespaces, unlike elements with white-space set to normal. The JSON.stringify method accepts three parameters:

  1. value: The value to convert to a JSON string, in our case, the users array.
  2. replacer: This is a function that we can use to change the stringification process. As we don't want any changes made to the output, we can safely set this to null.
  3. space: A string or number representing the number of spaces used for formatting the output. In our case, this will indent the JSON with 4 space tabs.

This will create a formatted string representation of the JSON object that is easy to read and debug.


Summary

In summary, fetching and displaying JSON data in React can be broken down into three main steps:

  • Prepare: Create a state using the useState hook and prepare the fetch in a useEffect hook.
  • Fetch: Fetch the data using the fetch API and store it inside the state using the updater function.
  • Display: Display the retrieved data to the user in a meaningful way.

If you are interested in learning more about React, be sure to check our guided roadmap below. Do you have any questions this tutorial did not cover? Let us know in the comment below! Thank you for reading, Happy coding. πŸ‘¨β€πŸ’»

Master React
  • twitter
  • facebook
React
Did you find this page helpful?
πŸ“š More Webtips
Frontend Course Dashboard
Master the Art of Frontend
  • check Access 100+ interactive lessons
  • check Unlimited access to hundreds of tutorials
  • check Prepare for technical interviews
Become a Pro

Courses

Recommended

This site uses cookies We use cookies to understand visitors and create a better experience for you. By clicking on "Accept", you accept its use. To find out more, please see our privacy policy.