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 */
}
|