Advertisement
Guest User

usePromise

a guest
Mar 16th, 2023
241
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import { DependencyList, useEffect, useState } from "react";
  2.  
  3. type PromiseFunction<T> = (signal: AbortSignal) => Promise<T>;
  4.  
  5. export type UsePromiseResult<T> =
  6.   | { status: "pending" }
  7.   | { status: "fulfilled"; value: T }
  8.   | { status: "rejected"; reason: unknown };
  9.  
  10. const resultPending: UsePromiseResult<never> = { status: "pending" };
  11.  
  12. export default function usePromise<T>(
  13.   promiseFunction: PromiseFunction<T>,
  14.   deps: DependencyList,
  15. ): UsePromiseResult<T> {
  16.   const [result, setResult] = useState<UsePromiseResult<T>>(resultPending);
  17.  
  18.   useEffect(() => {
  19.     let pending = true;
  20.     setResult(resultPending);
  21.     const abortController = new AbortController();
  22.     const promise = promiseFunction(abortController.signal);
  23.     promise.then(
  24.       (value) => {
  25.         if (pending) {
  26.           pending = false;
  27.           setResult({ status: "fulfilled", value });
  28.         }
  29.       },
  30.       (reason: unknown) => {
  31.         if (pending) {
  32.           pending = false;
  33.           setResult({ status: "rejected", reason });
  34.         }
  35.       },
  36.     );
  37.  
  38.     return () => {
  39.       if (pending) {
  40.         pending = false;
  41.         abortController.abort();
  42.       }
  43.     };
  44.     // eslint-disable-next-line react-hooks/exhaustive-deps
  45.   }, deps);
  46.  
  47.   return result;
  48. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement