import { useState, useCallback } from 'react'; type ActionState = { data: T | null; error: string | null; isPending: boolean; }; /** * A reusable hook for managing asynchronous operations. * It provides a clean API for handling pending, success (data), and error states * using a traditional useState/useCallback pattern for maximum compatibility and stability. * * @template T The expected data type of the action's successful result. * @template A The arguments tuple type for the action. * @param action The asynchronous function to execute. * @returns An object containing the action's state (`data`, `error`), pending status (`isPending`), an `execute` function, and a `reset` function. */ export function useAction(action: (...args: A) => Promise) { const [state, setState] = useState>({ data: null, error: null, isPending: false, }); const execute = useCallback( async (payload: A) => { setState({ data: null, error: null, isPending: true }); try { const data = await action(...payload); setState({ data, error: null, isPending: false }); return { data }; } catch (error) { const errorMessage = error instanceof Error ? error.message : 'An unknown error occurred.'; setState({ data: null, error: errorMessage, isPending: false }); return { error: errorMessage }; } }, [action] ); const reset = useCallback(() => { setState({ data: null, error: null, isPending: false }); }, []); return { data: state.data, error: state.error, isPending: state.isPending, execute, reset, }; }