import { useState, useEffect, useReducer, useRef } from 'react'; import axios from 'axios'; const instance = axios.create(); const dataFetchReducer = (state: any, { type, payload }: { type: string; payload?: any }) => { switch (type) { case 'FETCH_INIT': return { ...state, isLoading: true, isError: false }; case 'FETCH_SUCCESS': return { ...state, isLoading: false, isError: false, data: payload, }; case 'PROGRESS': return { ...state, progress: payload, }; case 'FETCH_FAILURE': return { ...state, isLoading: false, isError: true, }; default: throw new Error('未定义的action type'); } }; const useDataApi = (url: string, initialData: any = null) => { const [config, doUpload] = useState({ url }); const FirstRun = useRef(true); const [state, dispatch] = useReducer(dataFetchReducer, { isLoading: false, isError: false, progress: 0, data: initialData, }); useEffect(() => { if (FirstRun.current) { FirstRun.current = false; return; } let didCancel = false; const fetchData = async () => { dispatch({ type: 'FETCH_INIT' }); try { const result = await instance({ url, method: 'post', onUploadProgress: function(e) { if (e.lengthComputable) { dispatch({ type: 'PROGRESS', payload: (e.loaded / e.total) * 100 }); } }, ...config, }); if (!didCancel) { dispatch({ type: 'FETCH_SUCCESS', payload: result.data }); } } catch (error) { if (!didCancel) { dispatch({ type: 'FETCH_FAILURE' }); } } }; fetchData(); return () => { didCancel = true; }; }, [config]); return [state, doUpload, dispatch]; }; export default useDataApi;