UNPKG

@simonkov/use-axios

Version:

A custom React hook that provides a state-driven interface for Axios requests.

83 lines 2.81 kB
import axios, { AxiosError } from "axios"; import React, { useEffect } from "react"; import { flushSync } from "react-dom"; const RESET_STATE_FLAGS = { isFinished: false, isAborted: false, isLoading: false, isPending: false, isSuccess: false, isError: false, isConcurrencyFailure: false }; export function useAxios(requestConfig, options) { const invocationCount = React.useRef(0); const [state, setState] = React.useState({ ...RESET_STATE_FLAGS, response: null, error: null, isPending: true }); function request(config) { const mergedConfig = { ...requestConfig, ...config }; const request = (options?.instance || axios).request(mergedConfig); const maybeIntercepted = options?.intercept === undefined ? request : options.intercept(request); setState((curr) => ({ ...curr, ...RESET_STATE_FLAGS, isLoading: true })); return new Promise((resolve, reject) => { if (options?.preventConcurrent && invocationCount.current !== 0) { setState((curr) => ({ ...curr, ...RESET_STATE_FLAGS, isConcurrencyFailure: true })); const error = new AxiosError("Concurrency failure", "ERROR_CONCURRENCY_FAILURE", config); reject(error); return; } ++invocationCount.current; maybeIntercepted.then((response) => { queueMicrotask(() => { flushSync(() => { setState((curr) => ({ ...curr, ...RESET_STATE_FLAGS, isFinished: true, isSuccess: true, response })); resolve(response); }); }); }) .catch((error) => { queueMicrotask(() => { flushSync(() => { setState((curr) => ({ ...curr, ...RESET_STATE_FLAGS, isFinished: true, isError: true, error })); reject(error); }); }); }) .finally(() => { --invocationCount.current; }); }); } if (options?.immediate) { useEffect(() => { request(requestConfig); }, []); return state; } return [request, state]; } //# sourceMappingURL=main.js.map