Often times we are faced with difficulty in tracking the request status while making api calls on our react app. Request status here could be the data response, loading status, error encountered, etc.
The work around is usually to create individual useState to manage all the status that we want (like error, data, etc).
This hook is built on top of javascript axios package
First, let’s create the useAxios custom hooks
//useAxios.js
import { useState, useEffect } from "react";
import axios from "axios";
const useAxios = props => {
const [axiosData, setAxiosData] = useState({
url: null,
method: "GET",
body: null,
headers: null
});
const [data, setData] = useState(null);
const [error, setError] = useState(null);
const [loading, setLoading] = useState(false);
const [status, setStatus] = useState(null);
const sourceToken = axios.CancelToken.source();
const fetchApi = async () => {
setLoading(true);
setData(null);
setError(null);
setStatus(null);
try {
const data = axiosData?.body ? { data: axiosData?.body } : {};
const headers = axiosData?.headers ? { headers: axiosData?.headers } : {};
const response = await axiosClient({
url: axiosData.url,
method: axiosData.method ?? "GET",
cancelToken: sourceToken.token,
...data,
...headers,
});
setLoading(false);
setStatus(response?.status);
setData(response?.data);
if (props.onSuccess) props.onSuccess(response?.data);
} catch (error) {
const errorMsg = error?.message;
setLoading(false);
setError(String(errorMsg));
setStatus(error?.response?.status);
if (props.onError) props.onError(errorMsg);
}
};
useEffect(() => {
if (axiosData.url != null) {
fetchApi();
}
// abort the fetch if screen is dead/inactive
return () => sourceToken.cancel();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [axiosData]);
// return [setPostData, data, error, loading, status];
return { axios: setAxiosData, data, error, loading, status };
};
export default useAxios;
Initialize request with useAxios
To initialize your request
//index.js
import useAxios from "customHooks/useAxios";
const { axios, data, error, loading, status } = useAxios();
axios: custum axios function to make the api request
data: reponse data from the endpoint
error: contains error message if an error occures
status: returns status code of the request
To trigger the api request, for instance when a button is clicked
const onClick = ()=>{
axios({
url: "https://example.com"
});
}
This makes a get request to https://example.com
The axios function can accept multiple parameters like method, body, and headers
What about POST/PATCH/DELETE requests
To make a request with a custom methods, you could do
const onClick = ()=>{
const data = {
name:"Sample name",
category:"sampleCat",
}
axios({
url: "https://example.com",
method:"POST",
body:data,
headers:{...}
});
}
You can also also listen for success or error response while initializing the useAxios. Here is how you can do this,
const { axios, data, error, loading, status } = useAxios({
onSuccess: (data) => {
console.log(data);
},
onError: (error) => {
console.log(error);
}
});
onSuccess is fired when the data is returned from the endpoint
onError is fired when an error occurs.
You can as well enhance the
useAxios hook
to includebase url
,token
, etc...
Thanks for reading!
Top comments (0)