dndbeyond_src/ddb_main/hooks/useApiCall.ts
2025-05-28 15:36:51 -07:00

49 lines
1.4 KiB
TypeScript

import { useCallback, useState } from "react";
const identity = (x) => x;
/**
* Hook that encapsulates loading/error state setting when calling an API promise
* Usage:
* const [
* doThing, // callback to invoke to initiate the API call
* isDoingThing, // boolean indicating if the API call is in progress
* errorDoingThing, // error object indicating if there was an error caught (whatever param is passed to the .catch() callback)
* ] = useApiCall(MyApiUtils.doThing);
* @param {function} apiFunc The API function to use for setting loading/error state - Must return a promise!
* @param {function} [onSuccess] Optional callback invoked if the apiFunc promise succeeds
* @returns {[function, boolean, any]} An array containing a callback to initiate the API call, a isLoading boolean, and an error object
*/
const useApiCall = (apiFunc, onSuccess = identity) => {
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState(null);
const makeCall = useCallback(
(...args) => {
setIsLoading(true);
setError(null);
apiFunc(...args)
.then(onSuccess)
.then(() => {
setIsLoading(false);
})
.catch((err) => {
setIsLoading(false);
setError(err);
});
},
[apiFunc, onSuccess]
);
return [
makeCall as (...args: any[]) => void,
isLoading as boolean,
error as any,
];
};
export default useApiCall;