axios cancelToken 요청 취소

RIHO·2024년 5월 21일

몇 달 전 진행하였던 프로젝트에서 사용자로 하여금 HTTP 요청을 취소하게끔 하는 기능을 구현할 일이 있었는데, 간만에 소스 찾아보다가 기록해두면 좋을 것 같은 내용이라 게시글을 작성함.

Axios는 cancelToken 토큰을 통해 사용자 요청 취소 기능을 제공한다.

const CancelToken = axios.CancelToken;
const source = CancelToken.source();

axios.get('/user/12345', {
  cancelToken: source.token
}).catch(function (thrown) {
  if (axios.isCancel(thrown)) {
    console.log('Request canceled', thrown.message);
  } else {
    // 에러 핸들링
  }
});

axios.post('/user/12345', {
  name: 'new name'
}, {
  cancelToken: source.token
})

// 요청 취소하기 (메시지 파라미터는 옵션입니다)
// 요청을 취소할 때 하단 source.cancel을 호출
source.cancel('Operation canceled by the user.'); 

또는

const CancelToken = axios.CancelToken;
let cancel;

axios.get('/user/12345', {
  cancelToken: new CancelToken(function executor(c) {
    // 실행자 함수는 취소 함수를 파라미터로 받습니다.
    cancel = c;
  })
});

// 요청 취소하기
cancel();

와 같은 방법으로 axios 요청 취소 구현이 가능하다.
(출처: https://axios-http.com/kr/docs/cancellation)

이때 나는 HTTP 통신이 이루어지는 컴포넌트와는 다른 컴포넌트에서 취소 요청을 조작해야 하는 상황이었기에, 상단 예시 소스를 그대로 사용하기에는 무리가 있었다.

그래서 Zustand를 이용하여 store에 취소 함수를 저장하였다.
다른 상태 관리 라이브러리를 사용하고 있다면 그걸 이용해도 괜찮지 않을까? 일단 나는 Zustand를 사용하고 있었기 때문에...
실제 구현 방식은 다음과 같다.

store.ts

type CancelStoreType = {
  setCancel: (c: Canceler) => void;
  cancel: () => void;
};

export const useCancelStore = create<CancelStoreType>((set) => ({
  setCancel: (c) => set({ cancel: c }),
  cancel: () => {
    return;
  },
}));
await axios
        .post(
          `apl/url...`,
          {
            data,
          },
          {
            cancelToken: new CancelToken(function executor(c) {
              setCancel(c);
            }),
          },
        )
        .then((res) => ...)
...
...
...

// 실제 취소 실행 구간
  const onCancle = () => {
      if (confirm('취소하시겠습니까?')) {
        cancel?.();
      } else return;
  };

이와 같이 구현하면, 다른 컴포넌트에서도 cancel state를 import 후 cancel?.() 실행 시 axios 요청이 원활하게 취소된다.

profile
Front-End / 기록용

0개의 댓글