Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | 9x 9x 7x 7x 6x 5x | import { DependencyList, EffectCallback, useEffect } from "react"; import { useMounted } from "../useMounted"; /** * This starts an async function and executes another function that performs * React state changes if the component is still mounted after the `async` * operation completes. This uses {@link useMounted} for handling the * mount logic. * @param asyncFunction - async function, * it has a copy of the mounted ref so an await chain can be canceled earlier. * this should ideally be wrapped with useCallback to prevent rerenders * @param onSuccess - this gets executed after async * function is resolved and the component is still mounted * this should ideally be wrapped with useCallback to prevent rerenders * @param deps - dependency list */ export function useAsyncSetEffect<T>( asyncFunction: () => Promise<T>, onSuccess: (asyncResult: T) => void, deps: DependencyList = [] ): void { const isMounted = useMounted(); // eslint is disabled since the deps are needed in this csae /* eslint-disable react-hooks/exhaustive-deps */ useEffect((): ReturnType<EffectCallback> => { (async function wrapped() { const asyncResult = await asyncFunction(); if (isMounted()) { onSuccess(asyncResult); } })(); }, [asyncFunction, isMounted, onSuccess, ...deps]); /* eslint-enable react-hooks/exhaustive-deps */ } |