React: Axios hook with typescript
Axios is great library for data fetching, having over 17M+ monthly downloads, lets create a custom hook for our react app.
What we need?
- State
- Axios function to call.
Let's start writing our code, first declare a generic function hook useAxios
const useAxios = <T extends {}>() => {}
Now our state part
const [data, setData] = React.useState<T>();
const [loading, setLoading] = React.useState(false);
const [error, setError] = React.useState({});
See I have used <T> which means our state will be same as type T
const loadData = React.useCallback(
async (
endpoint: string,
body?: any,
config?: AxiosRequestConfig,
method: "get" | "post" | "delete" | "patch" = "get"
) => {
setLoading(true);
await axios[method]<T>(endpoint, body, config)
.then((res) => {
setData(res.data);
setLoading(false);
})
.catch((err) => {
setError(err);
setLoading(false);
});
},
[]
);
This would be our function which will call the axios, axios[method]
will call any one of method from get, post, patch, delete.
Now return all the data
return { data, loading, error, loadData };
Now let's define our expected response type
type ResponseType = {
userId: number;
id: number;
title: string;
body: string;
};
and let's write our react component
export const MyComponent = (): JSX.Element => {
const { data, error, loadData, loading } = useAxios<ResponseType>();
React.useEffect(() => {
loadData("https://jsonplaceholder.typicode.com/posts/1");
}, []);
return (
<div>
{loading && "Loading..."}
{data && (
<div>
{data.title}
{data.userId}
</div>
)}
{error && JSON.stringify(error)}
</div>
);
};
So whole code would look like
import React from "react";
import axios, { AxiosRequestConfig } from "axios";
const useAxios = <T extends {}>() => {
const [data, setData] = React.useState<T>();
const [loading, setLoading] = React.useState(false);
const [error, setError] = React.useState({});
const loadData = React.useCallback(
async (
endpoint: string,
body?: any,
config?: AxiosRequestConfig,
method: "get" | "post" | "delete" | "patch" = "get"
) => {
setLoading(true);
await axios[method]<T>(endpoint, body, config)
.then((res) => {
setData(res.data);
setLoading(false);
})
.catch((err) => {
setError(err);
setLoading(false);
});
},
[]
);
return { data, loading, error, loadData };
};
type ResponseType = {
userId: number;
id: number;
title: string;
body: string;
};
export const MyComponent = (): JSX.Element => {
const { data, error, loadData, loading } = useAxios<ResponseType>();
React.useEffect(() => {
loadData("https://jsonplaceholder.typicode.com/posts/1");
}, []);
return (
<div>
{loading && "Loading..."}
{data && (
<>
{data.title}
{data.userId}
</>
)}
{error && JSON.stringify(error)}
</div>
);
};
Thanks for your time, see you next time!!