import axios, { AxiosError, AxiosPromise } from 'axios';
import { useCallback, useState } from 'react';
import { useNavigate } from 'react-router-dom';
export default function useAxios<T>(
axiosFunction: (arg?: any) => AxiosPromise<T>,
): [(arg?: any) => Promise<void>, boolean, AxiosError | Error | null, T | null] {
const [loading, setLoading] = useState<boolean>(false);
const [error, setError] = useState<AxiosError | Error | null>(null);
const [data, setData] = useState<T | null>(null);
const navigate = useNavigate();
const request = useCallback(
async (arg?: any) => {
setLoading(true);
setError(null);
setData(null);
try {
const response = await axiosFunction(arg);
setData(response.data);
} catch (err) {
setData(null);
if (axios.isAxiosError(err)) {
~~if (!err.response) { // network error면
navigate('/error'); // ErrorPage로 이동
return;
}~~
setError(err);
} else {
setError(new Error('unexpected error'));
}
}
setLoading(false);
},
[axiosFunction],
);
return [request, loading, error, data];
}
// /src/axios/requests/signupRequest.ts
import axiosBackend from '../instances/axiosBackend';
interface FormData {
id: string;
nickname: string;
password: string;
}
export default (formData: FormData) => {
return axiosBackend.post(`/user/signup`, formData);
};
기본 : loading===true일 경우 <Loading />혹은 <LoadingLayer/>를 렌더링한다.
방안1
// 컴포넌트 내부
if (loading){
return <Loading />
}
return (
<div>content</div>
)
방안2
// 컴포넌트 내부
return (
<>
{loading && <LoadingLayer />}
<div>content</div>
</>
)
혹은 각 컴포넌트에 적합한 처리