create-plume-react-project
Version:
CLI to create Plume React Project
49 lines (44 loc) • 1.67 kB
text/typescript
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<T>(
dataPromise: () => LoadingPromise<T>,
dependencies: DependencyList = [],
): DataLoader<T> {
const [data, setData] = useState<T>();
const isMountedRef: MutableRefObject<boolean> = useRef<boolean>(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,
};
}