Skip to content

Instantly share code, notes, and snippets.

@g4rcez
Created December 2, 2020 17:42
Show Gist options
  • Save g4rcez/a48e989fb7d68b4f36c1890e264eafcf to your computer and use it in GitHub Desktop.
Save g4rcez/a48e989fb7d68b4f36c1890e264eafcf to your computer and use it in GitHub Desktop.
import axios, { AxiosInstance, AxiosRequestConfig, AxiosStatic, CancelTokenSource } from "axios";
import { useCallback, useEffect, useMemo, useRef } from "react";
type Tokens = { [k: string]: CancelTokenSource | undefined };
const createUid = () => Math.random().toString(36).substring(16);
type Http = "get" | "head" | "options" | "delete";
type HttpBody = "post" | "put" | "patch";
export const useAxios = (axiosInstance: AxiosInstance | AxiosStatic = axios) => {
const requests = useRef<Tokens>({});
useEffect(() => () => {
(Object.values(requests.current) as CancelTokenSource[])
.filter((x) => !!x?.cancel)
.forEach((x) => x?.cancel("Component unMount"));
});
const createWithoutBody = useCallback(
(method: Http) => async <Res>(url: string, options?: AxiosRequestConfig) => {
const uid = createUid();
const cancelToken = axios.CancelToken;
const source = cancelToken.source();
requests.current[uid] = source;
try {
const response = await axiosInstance[method]<Res>(url, { ...options, cancelToken: source.token });
requests.current[uid] = undefined;
return response;
} catch (error) {
throw error;
}
},
[axiosInstance]
);
const createWithBody = useCallback(
(method: HttpBody) => async <Res, Body = any>(url: string, body: Body, options?: AxiosRequestConfig) => {
const uid = createUid();
const cancelToken = axios.CancelToken;
const source = cancelToken.source();
requests.current[uid] = source;
try {
const response = await axiosInstance[method]<Res>(url, body, { ...options, cancelToken: source.token });
requests.current[uid] = undefined;
return response;
} catch (error) {
throw error;
}
},
[axiosInstance]
);
const newAxios = useMemo(
() => ({
post: createWithBody("post"),
put: createWithBody("put"),
patch: createWithBody("patch"),
get: createWithoutBody("get"),
delete: createWithoutBody("delete"),
options: createWithoutBody("options"),
head: createWithoutBody("head")
}),
[createWithoutBody, createWithBody]
);
return newAxios;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment