import React, { useState } from "react"; export function useLoading Promise>( action: T ) { const [loading, setLoading] = useState(false); const [success, setSuccess] = useState(false); const [error, setError] = useState(undefined); let isMounted = true; React.useEffect(() => { isMounted = true; return () => { isMounted = false; }; }, []); const doAction = async (...args: Parameters) => { setLoading(true); setSuccess(false); setError(undefined); return new Promise((resolve) => { action(...args) .then((v) => { if (!isMounted) return resolve(undefined); setSuccess(true); resolve(v); }) .catch((err) => { if (isMounted) { setError(err); setSuccess(false); } resolve(undefined); }); }).finally(() => isMounted && setLoading(false)); }; return [doAction, loading, error, success]; }