| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263 |
- import axios, { Canceler, AxiosInstance, AxiosResponse } from 'axios';
- import { useCallback, useEffect, useRef, useState } from 'react';
- type Options<Query, Response> = {
- sendRequest: (axiosInstance: AxiosInstance, query: Query) => Promise<AxiosResponse<Response>>;
- onError?: (err: Error) => void;
- };
- export function useRequestCallback<Query, Response = void>({
- onError,
- sendRequest,
- }: Options<Query, Response>): [(query: Query) => void, Response | null, boolean] {
- const [response, setResponse] = useState<Response | null>(null);
- const [loading, setLoading] = useState<boolean>(false);
- const cancel = useRef<() => void>();
- useEffect(() => (): void => cancel.current?.(), []);
- const onRequest = useCallback(
- (query: Query) => {
- let cancelled = false;
- let cancelRequest: Canceler | null = null;
- cancel.current?.();
- cancel.current = (): void => {
- cancelled = true;
- cancelRequest?.();
- };
- const axiosWithToken = axios.create({
- cancelToken: new axios.CancelToken((token): void => {
- cancelRequest = token;
- }),
- });
- const makeRequest = async (): Promise<void> => {
- try {
- setLoading(true);
- const res = await sendRequest(axiosWithToken, query);
- if (!cancelled) {
- setResponse(res.data);
- }
- } catch (err) {
- if (!axios.isCancel(err)) {
- onError?.(err);
- }
- } finally {
- if (!cancelled) {
- setLoading(false);
- }
- }
- };
- makeRequest();
- },
- [onError, sendRequest],
- );
- return [onRequest, response, loading];
- }
|