UNPKG

@mirawision/reactive-hooks

Version:

A comprehensive collection of 50+ React hooks for state management, UI interactions, device APIs, async operations, drag & drop, audio/speech, and more. Full TypeScript support with SSR safety.

66 lines (65 loc) 2.09 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.useAsync = useAsync; const react_1 = require("react"); /** * A hook that wraps an async function with state management. * @param fn The async function to wrap * @param deps Optional dependencies array that will trigger function reference update * @returns AsyncState object containing run function, data, error, loading state, and reset function */ function useAsync(fn, deps = []) { const [state, setState] = (0, react_1.useState)({ data: null, error: null, loading: false, }); // Keep track of the latest call to handle race conditions const callIdRef = (0, react_1.useRef)(0); const fnRef = (0, react_1.useRef)(fn); // Update function ref when function or deps change (0, react_1.useEffect)(() => { fnRef.current = fn; }, [fn, ...deps]); const run = (0, react_1.useCallback)(async (...args) => { const callId = ++callIdRef.current; setState(prev => ({ ...prev, loading: true, error: null })); try { const data = await fnRef.current(...args); // Ignore result if a newer call has started if (callId !== callIdRef.current) return data; setState(prev => ({ ...prev, data, loading: false, error: null, })); return data; } catch (error) { // Ignore error if a newer call has started if (callId !== callIdRef.current) throw error; setState(prev => ({ ...prev, error, loading: false, })); throw error; } }, [] // Empty deps array since we handle updates via fnRef ); const reset = (0, react_1.useCallback)(() => { setState({ data: null, error: null, loading: false, }); }, []); return { ...state, run, reset, }; }