만약, axios 를 통해 API 와 통신할 때 token
이라던지,
유저가 가진 권한
같은 특정 데이터가 들어가야한다고 해보자.
기존의 방식이라면 get
또는 post
시 매번 동일한 데이터를 넣어줘야한다.
하지만 axios interceptors
를 사용하면, 매번 작성하지 않아도 된다!
공식문서의 예제이다.
then 또는 catch로 처리되기 전에 요청과 응답을 가로챌수 있습니다.
// 요청 인터셉터 추가하기
axios.interceptors.request.use(function (config) {
// 요청이 전달되기 전에 작업 수행
return config;
}, function (error) {
// 요청 오류가 있는 작업 수행
return Promise.reject(error);
});
// 응답 인터셉터 추가하기
axios.interceptors.response.use(function (response) {
// 2xx 범위에 있는 상태 코드는 이 함수를 트리거 합니다.
// 응답 데이터가 있는 작업 수행
return response;
}, function (error) {
// 2xx 외의 범위에 있는 상태 코드는 이 함수를 트리거 합니다.
// 응답 오류가 있는 작업 수행
return Promise.reject(error);
});
const myInterceptor = axios.interceptors.request.use(function () {/*...*/});
axios.interceptors.request.eject(myInterceptor);
const instance = axios.create();
instance.interceptors.request.use(function () {/*...*/});
프로젝트에 첫 적용할 당시에는 신세계를 엿 본것 같은 기분이였는데,
생각해보니 여기에는 리액트 HOOK 을 적용할 수 없었다.
그 이유는, 리액트 공식문서에도 나와있 듯,
오직 React 함수 내에서 Hook을 호출해야 합니다.
그말인 즉슨 위에서 보고 있는 예제 interceptors
에는 리액트 훅을 추가할 수 없다는 말이다.
내 프로젝트는 axios
로 api
와 통신하는 것을 커스텀 훅으로 만들어서 사용하고 있었기 때문에, 예제와는 다른 방법이 필요했다.
아래는 instance
사용한 방법이다.
아래는 공식문서에 나와있는 예제이다.
const instance = axios.create({
baseURL: 'https://some-domain.com/api/',
timeout: 1000,
headers: {'X-Custom-Header': 'foobar'}
});
아래와 같이 인스턴스를 생성해준다.
변수명은 꼭 api
가 아니여도된다!
// --- 💥 axios 인스턴스 생성 💥
const api = axios.create({
baseURL: "http://www.togetherlab.co.kr",
timeout: 10000,
});
그리고 이 api
를 사용해서, 아래와 같이 사용해주면 된다.
나는 useAxiosInterceptor
라는 커스텀 훅으로 만들어줬다.
변수명이 조금 긴 것 같지만...가장 직관적이라 이걸루..ㅎㅎ 까먹진 않을듯?..
const useAxiosInterceptor = () => {
const token = useSelector((state) => state.authSlice.token);
const navigate = useNavigate();
const errorHandler = (error) => {
console.log("errInterceptor!", error);
if (error.response.status === 401) {
navigate("/");
}
return Promise.reject(error);
};
const requestHandler = (config) => {
config.headers = {
Authorization: !!token ? `Bearer ${token}` : "",
};
return config;
};
const responseHandler = (response) => {
return response;
};
const requestInterceptor = api.interceptors.request.use(requestHandler);
const responseInterceptor = api.interceptors.response.use(
(response) => responseHandler(response),
(error) => errorHandler(error.response.data)
);
useEffect(() => {
return () => {
api.interceptors.request.eject(requestInterceptor);
api.interceptors.response.eject(responseInterceptor);
};
}, [responseInterceptor, requestInterceptor]);
};
export { useAxiosInterceptor, api };
이렇게 만들어준 커스텀훅은 App.jsx
에 적어주면 된다!
// -App.jsx
function App() {
useAxiosInterceptor(); <<-- 추가!
return (
<...>
...
</...>
그럼 끝!