import { useState, useEffect, useRef, useReducer } from "react"; export type RequestContext = { data?: DataType; error?: any; loading: boolean; refresh: () => void; } /** * @param p * @returns * @todo deal refresh when loading */ const useRequest = (p: () => Promise, dependences?: any[]): RequestContext => { const [data, setData] = useState() const [error, setError] = useState(); 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;