rmux-fetch
Version:
137 lines (129 loc) • 2.77 kB
text/typescript
import { fetchWebapi, formDataType, useReducer } from '@/utils';
type URLFn = (opts: any) => string;
type URL = string | URLFn;
export interface UseFetchOpts {
formdata?: boolean;
url: URL;
method: string;
body?: any;
extraOpts?: object;
initialData?: any;
}
export interface RequsetParams {
body: object;
URLOptions: object;
}
interface CreateRequstOpts {
url: URL;
body: any;
params: object | RequsetParams;
}
export interface UseBaseFetchOpts extends UseFetchOpts {
fetch: any;
}
const initialState = {
loading: false,
error: {},
isFinally: false,
response: {},
isSuccess: false,
isError: false
};
function reducer(state: any, action: any) {
switch (action.type) {
case 'start':
return {
...state,
loading: true,
isFinally: false,
isSuccess: false,
isError: false
};
case 'error':
return {
...state,
error: action.error,
loading: false,
isFinally: true,
isSuccess: false,
isError: true
};
case 'success':
return {
...state,
response: action.data,
loading: false,
isFinally: true,
isSuccess: true,
isError: false
};
default:
return state;
}
}
export function useFetch(args: UseFetchOpts) {
return useBaseFetch({
...args,
fetch: fetchWebapi
});
}
const createRequst = ({ url, body, params }: CreateRequstOpts) => {
if (typeof url === 'function') {
url = url((params as RequsetParams).URLOptions);
body = (params as RequsetParams).body || body;
} else {
url = url;
body = params || body;
}
return {
url,
body
};
};
export function useBaseFetch({
initialData = {},
url,
method,
body,
fetch,
formdata = false, // 是否为formdata请求
extraOpts = {} // 额外的头部设置
}: UseBaseFetchOpts) {
const [
{ loading, error, isFinally, isSuccess, isError, response },
dispatch
] = useReducer(reducer, initialState, (s: any) => ({
...s,
response: initialData
}));
async function requestData(params?: any): Promise<any> {
try {
dispatch({ type: 'start' });
const { url: requestURL, body: requestBody } = createRequst({
url,
body,
params
});
const { data } = await fetch(requestURL, {
method,
body: requestBody,
headersType: formdata ? formDataType : undefined,
...extraOpts
});
dispatch({ type: 'success', data });
return data;
} catch (error) {
dispatch({ type: 'error', error });
throw error;
}
}
return {
loading,
error,
response,
doFetch: requestData,
isFinally,
isSuccess,
isError
};
}