[TIL] axios - interceptors 에 hook 사용하기

Leesu·2023년 5월 19일
2

[TIL] : Today I Learned

목록 보기
21/21

만약, axios 를 통해 API 와 통신할 때 token 이라던지,
유저가 가진 권한 같은 특정 데이터가 들어가야한다고 해보자.
기존의 방식이라면 get 또는 post 시 매번 동일한 데이터를 넣어줘야한다.

하지만 axios interceptors를 사용하면, 매번 작성하지 않아도 된다!


🟡 axios interceptors

공식문서의 예제이다.

- 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);
  });

- interceptors 삭제

const myInterceptor = axios.interceptors.request.use(function () {/*...*/});
axios.interceptors.request.eject(myInterceptor);

- custom interceptors에 interceptors 추가

const instance = axios.create();
instance.interceptors.request.use(function () {/*...*/});

프로젝트에 첫 적용할 당시에는 신세계를 엿 본것 같은 기분이였는데,
생각해보니 여기에는 리액트 HOOK 을 적용할 수 없었다.

그 이유는, 리액트 공식문서에도 나와있 듯,

오직 React 함수 내에서 Hook을 호출해야 합니다.

그말인 즉슨 위에서 보고 있는 예제 interceptors에는 리액트 훅을 추가할 수 없다는 말이다.

내 프로젝트는 axiosapi 와 통신하는 것을 커스텀 훅으로 만들어서 사용하고 있었기 때문에, 예제와는 다른 방법이 필요했다.

🟡 interceptors 에 hook 사용하기

아래는 instance 사용한 방법이다.

- instance 생성하는 방법

아래는 공식문서에 나와있는 예제이다.

const instance = axios.create({
  baseURL: 'https://some-domain.com/api/',
  timeout: 1000,
  headers: {'X-Custom-Header': 'foobar'}
});

- instance 생성

아래와 같이 인스턴스를 생성해준다.
변수명은 꼭 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 (
      <...>
          ...
      </...>

그럼 끝!

profile
기억력 안 좋은 FE 개발자의 메모장

0개의 댓글