Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import { DependencyList, useEffect, useState } from "react";
- type PromiseFunction<T> = (signal: AbortSignal) => Promise<T>;
- export type UsePromiseResult<T> =
- | { status: "pending" }
- | { status: "fulfilled"; value: T }
- | { status: "rejected"; reason: unknown };
- const resultPending: UsePromiseResult<never> = { status: "pending" };
- export default function usePromise<T>(
- promiseFunction: PromiseFunction<T>,
- deps: DependencyList,
- ): UsePromiseResult<T> {
- const [result, setResult] = useState<UsePromiseResult<T>>(resultPending);
- useEffect(() => {
- let pending = true;
- setResult(resultPending);
- const abortController = new AbortController();
- const promise = promiseFunction(abortController.signal);
- promise.then(
- (value) => {
- if (pending) {
- pending = false;
- setResult({ status: "fulfilled", value });
- }
- },
- (reason: unknown) => {
- if (pending) {
- pending = false;
- setResult({ status: "rejected", reason });
- }
- },
- );
- return () => {
- if (pending) {
- pending = false;
- abortController.abort();
- }
- };
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, deps);
- return result;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement