Skip to content

Instantly share code, notes, and snippets.

@g4rcez
Last active November 30, 2020 05:16
Show Gist options
  • Save g4rcez/be5f3d9cd5c20c4964a5c6f2d09d9a23 to your computer and use it in GitHub Desktop.
Save g4rcez/be5f3d9cd5c20c4964a5c6f2d09d9a23 to your computer and use it in GitHub Desktop.
use-axios hook to avoid memory leak on unmout react components
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;
}
},
[]
);
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;
}
},
[]
);
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