import { DependencyList, MutableRefObject, useEffect, useRef, useState, } from 'react'; import { DataLoader } from './observableLoaderHook'; import useLoader, { LoaderState, LoadingPromise } from './promiseLoaderHook'; /** * Hook used to load data in a compatible way with {@link DataLoader}. * * This hook can be used to create a single component that will be in charge to display * the loading status of the `Promise` and a retry button in case an error happened. * * @param dataPromise The function that makes the call that returns a `Promise`. * This function is called as soon as the component has been mounted, see {@link useOnComponentMounted}. * @param dependencies The dependencies that once updated should make the loader to reload the data */ export default function useDataLoader( dataPromise: () => LoadingPromise, dependencies: DependencyList = [], ): DataLoader { const [data, setData] = useState(); const isMountedRef: MutableRefObject = useRef(true); const loader: LoaderState = useLoader(); const dataLoader = () => loader.monitor(dataPromise().then((result: T) => { // don't update state if the component is unmounted to avoid errors if (isMountedRef) { setData(result); } })); useEffect(() => { // load the data as soon as the component is mounted or when the dependencies change dataLoader(); return () => { // mark the component as unmounted isMountedRef.current = false; }; }, dependencies); return { isLoaded: loader.isLoaded, isLoading: loader.isLoading, error: loader.error, loader: dataLoader, data, }; }