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
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.