UNPKG

@yamada-ui/react

Version:

React UI components of the Yamada, by the Yamada, for the Yamada built with React and Emotion

61 lines (57 loc) 1.63 kB
"use client"; import { useMounted } from "../use-mounted/index.js"; import { useCallback, useEffect, useRef, useState } from "react"; //#region src/hooks/use-async/index.ts /** * `useAsync` is a custom hook that executes an asynchronous function and tracks its state. * * @see https://yamada-ui.com/docs/hooks/use-async */ function useAsync(func, deps = []) { const [state, callback] = useAsyncFunc(func, deps, { loading: true }); useEffect(() => { callback(); }, [callback]); return state; } function useAsyncFunc(func, deps = [], initialState = { loading: false }) { const lastCallId = useRef(0); const mounted = useMounted(); const [state, setState] = useState(initialState); return [state, useCallback((...args) => { const callId = ++lastCallId.current; if (!state.loading) setState((prevState) => ({ ...prevState, loading: true })); return func(...args).then((value) => { if (mounted() && callId === lastCallId.current) setState({ loading: false, value }); return value; }, (error) => { if (mounted() && callId === lastCallId.current) setState({ error, loading: false }); return error; }); }, deps)]; } function useAsyncRetry(func, deps = []) { const [attempt, setAttempt] = useState(0); const state = useAsync(func, [...deps, attempt]); const stateLoading = state.loading; const retry = useCallback(() => { if (stateLoading) return; setAttempt((currentAttempt) => currentAttempt + 1); }, [...deps, stateLoading]); return { ...state, retry }; } //#endregion export { useAsync, useAsyncFunc, useAsyncRetry }; //# sourceMappingURL=index.js.map