xfflod-resCenter/src/utils/useRequest.ts

52 lines
1.2 KiB
TypeScript

import { useState, useEffect, useRef, useReducer } from "react";
export type RequestContext<DataType> = {
data?: DataType;
error?: any;
loading: boolean;
refresh: () => void;
}
/**
* @param p
* @returns
* @todo deal refresh when loading
*/
const useRequest = <DataType = any>(p: () => Promise<DataType>, dependences?: any[]): RequestContext<DataType> => {
const [data, setData] = useState<DataType | undefined>()
const [error, setError] = useState<any>();
const [loading, setLoading] = useState(false);
const abort = useRef(false);
const [_, refresh] = useReducer(s => s + 1, 0);
useEffect(() => {
const doFetch = async () => {
setLoading(true);
abort.current = false;
try {
const data = await p();
if (!abort.current) {
setData(data);
}
} catch (e) {
if (!abort.current) {
setError(e);
}
} finally {
if (!abort.current) {
setLoading(false);
}
}
};
doFetch();
return () => {
abort.current = true;
};
}, dependences ? [...dependences, _] : [_]);
return { data, error, loading, refresh };
};
export default useRequest;