import { AxiosRequestConfig, AxiosResponse } from "axios"; import { useCallback, useReducer } from "react"; import { useAxios } from "./useAxios"; type ReducerActionStart = { type: "start" } type ReducerActionDone = { type: "done", response: AxiosResponse } type ReducerActionError = { type: "error", error: any } type ReducerAction = ReducerActionStart | ReducerActionDone | ReducerActionError type ReducerState = { running: boolean, response: AxiosResponse | undefined, error: any | undefined, } export function useAxiosRequest(config: AxiosRequestConfig = {}, onSuccess?: (response: AxiosResponse) => void, onError?: (error: any) => void) { const axios = useAxios() const [state, dispatch] = useReducer( (prev: ReducerState, action: ReducerAction) => { switch (action.type) { case "start": return { running: true, response: undefined, error: undefined, } case "done": return { running: false, response: action.response, error: undefined, } case "error": return { running: false, response: action.error.response, error: action.error } } }, { running: false, response: undefined, error: undefined, } ) const run = useCallback( async (funcConfig: AxiosRequestConfig = {}) => { dispatch({ type: "start" }) try { var response: AxiosResponse = await axios.request({ ...config, ...funcConfig }) } catch (error) { dispatch({ type: "error", error }) onError?.(error) return } dispatch({ type: "done", response }) onSuccess?.(response) }, [axios] ) return { running: state.running, response: state.response, data: state.response?.data as T | undefined, error: state.error, run, } }