모바일 웹에서 프로젝트를 만들며 api 요청 시간이 조금 소요되는 api가 있습니다. 문제는 이 api 요청 중에 다른 페이지로 이동하면 요청이 pending 상태에 계속 머물게 된다는 것인데요.
아래 사진으로 설명해보겠습니다.
API 요청 pending
[홈]에서 요청했던 plcProduction이라는 api 요청이 다른 페이지로 이동해도 여전히 pending입니다.


이것이 왜 문제가 되냐하면, 유저가 페이지를 빠르게 여러번 이동하면 pending 요청이 쌓이게됩니다.
만약 빠르게 4번을 왔다 갔다 한다면 4개의 pending이 쌓이게 되겠죠?

이를 해결하기 위해 찾아보니 axios에서는 CancelToken을 제공한다는 것을 알았습니다.
axios CancelToken 적용
기존 api 요청 코드
// 참고로 리액트입니다!
const fetchData = async () => {
try {
const res = await axios.get(
`${import.meta.env.VITE_SERVER_URL}/plcProduction`
);
setPlcProduction(res.data);
} catch (error) {
console.log(error);
}
};
cancelToken 적용
const fetchData = async (source: CancelTokenSource) => {
try {
const res = await axios.get(
`${import.meta.env.VITE_DB_SERVER_URL}/plcProduction`,
{ cancelToken: source.token }
);
setPlcProduction(res.data);
} catch (error) {
console.error("Error fetching data:", error);
}
};
useEffect(() => {
const source = axios.CancelToken.source();
fetchData(source);
return () => {
source.cancel("Component unmounted");
};
}, []);
특별히 어려울 것은 없지만, 중요한 것은 axios.CancelToken.source() 생성을 useEffect 내에서 해줘야 한다는 것인데요.
그래야 컴포넌트가 마운트될 때마다 새로운 토큰을 생성하기 때문입니다. 그렇지 않으면 리렌더링 되어도 cancel 상태가 적용된 토큰을 사용하게 되고, 새로운 api 요청을 하지 않게 됩니다.
결과
이제 pending 상태에서 페이지를 이동하게 되면 status가 canceled되는 것을 알 수 있다. cancel을 적용한 덕분에 db connection pool에 요청이 쌓이지 않게 됩니다.


그 외 더 다양한 방법을 알고 싶으시다면 아래 참고자료 블로그를 추천드립니다!
참고 자료
1. https://velog.io/@eunbinn/cancel-promises-javascript?utm_source=substack&utm_medium=email
[번역] 자바스크립트에서 프로미스를 취소하는 방법
보통 fetch는 signal, XHR은 abort를 사용해 요청을 취소하는데요, 일반적인 프로미스는 어떻게 취소할 수 있을까요? 이 글에서는 그 방법으로 프로미스의 결과를 폐기 또는 무시하는 방법을 설명하고
velog.io
2.
https://axios-http.com/kr/docs/cancellation
요청 취소 | Axios Docs
요청 취소 취소 토큰을 이용해 요청을 취소할 수 있습니다. Axios의 취소 토큰 API는 중단된 proposal-cancelable-promises을 기반으로 하고 있습니다. 아래와 같이 CancelToken.source 팩토리를 사용하여 취소
axios-http.com
'프로그래밍⚡️ > React' 카테고리의 다른 글
리액트에서 일정 간격 반복적으로 api 호출하기 refetchInterval (1) | 2023.07.10 |
---|---|
input의 불필요한 렌더링이 줄이기 State Colocation(상태 공존)과 함께 (0) | 2023.03.26 |
재사용성을 높이는 디자인과 컴포넌트에 대한 이야기 (0) | 2023.03.19 |
React-hook의 종류와 custom hook 사용기 (0) | 2023.02.24 |
함수 안에서 어떻게 setState가 두번 작동하지? (micro queue, macro queue) (0) | 2023.02.22 |