한달인턴 프리온보딩 과제 진행 중에 axios에서 반복되는 catch문 코드가 굉장히 신경쓰였다.
사실 oosie 프로젝트 때도 똑같은 문제가 있었는데 그때는 바빠서 눈에 들어오지 않았음.. 시간나면 리팩토링을 진행해야겠다 ^^
이때 알게된 것이 interceptor이다. 이거는 OOSIE 프로젝트 최종 발표일에 세이지의 면접 코치(?)님이 언급하셔서 존재만 알고 있었다. 써보니까 코치님이 이 기능을 좋아하시는 이유를 알겠더라.. 너무 조아ㅏㅏㅏ!!!!!!!
axios는 fetch보다 더 다양한 기능을 제공하는 라이브러리이고, 요청과 응답을 가로챌 수 있는 interceptor 기능 또한 제공한다.
docs를 보면 then 또는 catch로 처리되기 전에 요청과 응답을 가로챌수 있다고 한다.
client.interceptors.response.use(
(response) => response,
(error) => {
if (axios.isAxiosError(error)) {
throw new Error(error.response?.data.message);
}
throw error;
}
);
다음과 같은 코드를 이용하여 throw 코드를 interceptor로 분리하였다.
이렇게 되면, 아래와 같이 길었던 API 코드들에서
export async function register(data: RegisterType) {
try {
const response = await client.post("/register", data);
return response.data;
} catch (e) {
if (axios.isAxiosError(e)) throw new Error(e.response?.data.message);
throw e;
}
}
6줄을 줄일 수 있었다.
export async function register(data: RegisterType) {
const response = await client.post("/register", data);
return response.data;
}
401일때 login으로 리다이렉트하기 위해 interceptor에 switch문을 추가해주었다.
client.interceptors.response.use(
(response) => {
return response;
},
(error) => {
if (axios.isAxiosError(error))
// 추가
switch (error.response?.status) {
case 401:
console.log(401);
break;
default:
throw new Error(error.response?.data.message);
}
//
throw error;
}
);
근데 navigate를 쓰려고 하니까 컴포넌트 밖이라서 useNavigate를 쓸 수가 없다는 문제가 발생했다.
stack overflow에서 해답을 찾았다.
createBrowserRouter의 리턴값인 router를 export하고 인터셉터가 포함된 파일에서 import 받아서 이렇게 쓰면 가능했다. :D
router.navigate("/login");
axios interceptor로 401 처리하기 | 고광필 | velog
react router v6 navigate outside of components | stack overflow