React 18 Get and Cache Data with Custom Hook Tutorial

Last Updated on by in React JS

In this tutorial, we will learn how to create a custom hook in React js app. This custom hook fetches the data from the server with the help of a REST API.

We will also discover how to cache the api response using the custom hook in React js app using the useReducer, useEffect, and useRef hooks.

The useReducer hook is based on a redux pattern; It returns an array that contains the current state value and a dispatch method that is triggered based on the custom action. We will use the useReducer hook to manage the state.

We will bind it with the useRef hook; the useRef hook persists the values between renders.

It allows to persist values between renders and is theoretically used to store a mutable value that does not cause a re-render when updated. We are using useRef to access the DOM element directly.

How to Cache API Response using Custom Hook in React Js

  • Step 1: Create React Project
  • Step 2: Install Bootstrap Library
  • Step 3: Create Custom Hook
  • Step 4: Use useApi Hook in Component
  • Step 5: View App in Browser

Create React Project

Developing React app requires a particular environment; we will install Create React App tool in our development system for building React single-page applications.

npm install create-react-app --global

We have configured the react environment; now we can install a react app using the suggested command:

npx create-react-app react-demo

Let us get into the app folder and start learning to create a custom hook.

cd react-demo

Install Bootstrap Library

This step is completely optional; we are going to install the bootstrap library in react. Bootstrap framework is ideally used for rapid and eloquent web development.

npm install bootstrap --legacy-peer-deps

Head over to src/App.js folder, start importing bootstrap CSS path from the node modules folder:

import '../node_modules/bootstrap/dist/css/bootstrap.min.css'

Create Custom Hook

In the src/ directory, create a new file named custom-hook.js. Thereafter in this file you need to place the following code for creating a custom hook.

import { useEffect, useRef, useReducer } from 'react'

export const useApi = (api) => {
  const cacheData = useRef({})

  const initialState = {
    status: 'idle',
    error: null,
    data: [],
  }

  const [state, dispatch] = useReducer((state, action) => {
    switch (action.type) {
      case 'FETCHING':
        return { ...initialState, status: 'fetching' }
      case 'FETCHED':
        return { ...initialState, status: 'fetched', data: action.payload }
      case 'FETCH_ERROR':
        return { ...initialState, status: 'error', error: action.payload }
      default:
        return state
    }
  }, initialState)

  useEffect(() => {
    let revokeRequest = false
    if (!api || !api.trim()) return

    const renderData = async () => {
      dispatch({ type: 'FETCHING' })
      if (cacheData.current[api]) {
        const data = cacheData.current[api]
        dispatch({ type: 'FETCHED', payload: data })
      } else {
        try {
          const res = await fetch(api)
          const data = await res.json()
          cacheData.current[api] = data
          if (revokeRequest) return
          dispatch({ type: 'FETCHED', payload: data })
        } catch (error) {
          if (revokeRequest) return
          dispatch({ type: 'FETCH_ERROR', payload: error.message })
        }
      }
    }

    renderData()

    return function cleanup() {
      revokeRequest = true
    }
  }, [api])

  return state
}

We are handling api responses using the useReducer pattern; the useReducer hook handles the complex states in React.

We are making the request to the server using a real api; our custom hook is managing three states, fetching, fetched, and fetch error.

Use useApi Hook in Component

Open the src/App.js file; in this file, we need to import the useApi hook that we built in the previous step.

Use the object destructing to access the api response that is being managed by the custom hook.

import React from 'react'
import { useApi } from './custom-hook'
import '../node_modules/bootstrap/dist/css/bootstrap.min.css'

const App = () => {
  const api = 'https://jsonplaceholder.typicode.com/users'

  const { status, data, error } = useApi(api)

  return (
    <div className="container mt-5">
      <h2 className="mb-3">
        React Cache API Response with Custom Hook Example
      </h2>

      <div className="alert alert-primary mb-3 text-center">{status}</div>

      {
        <ul className="list-group">
          {data.map((item, index) => {
            return (
              <li key={index} className="list-group-item">
                {item.name}
              </li>
            )
          })}
        </ul>
      }
    </div>
  )
}

export default App

View App in Browser

We are gong to execute the following command and start the React script:

npm start

You may use the following URL to view the app if developing app locally:

http://localhost:3000

React Get and Cache Data with Custom Hook Tutorial

Conclusion

In this tutorial, we have learned how to create a custom hook in React app; this custom hook fetches the data from the server using a real api.

Not only but also, we have figured out how to use useReducer and useEffect hooks to build custom hooks and get and cache api responses in react js application.