mirror of
https://github.com/outline/outline.git
synced 2026-06-13 03:14:59 +03:00
084490ba6b
* Add rules * codemod: update-react-imports * Update babelrc
66 lines
1.8 KiB
TypeScript
66 lines
1.8 KiB
TypeScript
import { useState, useCallback, useEffect } from "react";
|
|
import useIsMounted from "./useIsMounted";
|
|
|
|
type RequestResponse<T> = {
|
|
/** The return value of the request function. */
|
|
data: T | undefined;
|
|
/** The request error, if any. */
|
|
error: unknown;
|
|
/** Whether the request is currently in progress. */
|
|
loading: boolean;
|
|
/** Whether the request has completed - useful to check if the request has completed at least once. */
|
|
loaded: boolean;
|
|
/** Function to start the request. */
|
|
request: () => Promise<T | undefined>;
|
|
};
|
|
|
|
/**
|
|
* A hook to make an API request and track its state within a component.
|
|
*
|
|
* @param requestFn The function to call to make the request, it should return a promise.
|
|
* @param makeRequestOnMount Whether to make the request when the component mounts.
|
|
* @returns An object containing the request state and a function to start the request.
|
|
*/
|
|
export default function useRequest<T = unknown>(
|
|
requestFn: () => Promise<T>,
|
|
makeRequestOnMount = false
|
|
): RequestResponse<T> {
|
|
const isMounted = useIsMounted();
|
|
const [data, setData] = useState<T>();
|
|
const [loading, setLoading] = useState<boolean>(false);
|
|
const [loaded, setLoaded] = useState<boolean>(false);
|
|
const [error, setError] = useState();
|
|
|
|
const request = useCallback(async () => {
|
|
setLoading(true);
|
|
try {
|
|
const response = await requestFn();
|
|
|
|
if (isMounted()) {
|
|
setData(response);
|
|
setError(undefined);
|
|
setLoaded(true);
|
|
}
|
|
return response;
|
|
} catch (err) {
|
|
if (isMounted()) {
|
|
setError(err);
|
|
}
|
|
} finally {
|
|
if (isMounted()) {
|
|
setLoading(false);
|
|
}
|
|
}
|
|
|
|
return undefined;
|
|
}, [requestFn, isMounted]);
|
|
|
|
useEffect(() => {
|
|
if (makeRequestOnMount) {
|
|
void request();
|
|
}
|
|
}, []);
|
|
|
|
return { data, loading, loaded, error, request };
|
|
}
|