@gqty/react
Version:
The No-GraphQL Client for React
66 lines (63 loc) • 1.7 kB
JavaScript
import { useSyncedRef } from '@react-hookz/web';
import { useState, useRef, useMemo } from 'react';
function useThrottledAsync(asyncFn, initialValue) {
const [state, setState] = useState({
status: "not-executed",
error: void 0,
result: initialValue
});
const promiseRef = useRef(void 0);
const argsRef = useRef(void 0);
const methods = useSyncedRef({
execute: (...params) => {
if (promiseRef.current) return promiseRef.current;
argsRef.current = params;
const promise = asyncFn(...params);
promiseRef.current = promise;
setState((s) => ({ ...s, status: "loading" }));
promise.then(
(result) => {
if (promise === promiseRef.current) {
setState((s) => ({
...s,
status: "success",
error: void 0,
result
}));
}
},
(error) => {
if (promise === promiseRef.current) {
setState((s) => ({ ...s, status: "error", error }));
}
}
).finally(() => {
if (promise === promiseRef.current) {
promiseRef.current = void 0;
}
});
return promise;
},
reset: () => {
setState({
status: "not-executed",
error: void 0,
result: initialValue
});
promiseRef.current = void 0;
argsRef.current = void 0;
}
});
return [
state,
useMemo(
() => ({
execute: (...args) => methods.current.execute(...args),
reset: () => methods.current.reset()
}),
[]
),
{ promise: promiseRef.current, lastArgs: argsRef.current }
];
}
export { useThrottledAsync };