-
React Strict Mode에서 API 사용Front-end/React 2023. 1. 17. 22:50728x90
yotrakbutda - White cloud on black background React 18 부터 Stric Mode development 환경에서는 컴포넌트가 두번 렌더링됩니다. 정확히 말하면 mount → unmount → remount의 lifecycle로 이루어집니다.
공식 문서: https://reactjs.org/docs/strict-mode.html#ensuring-reusable-state
Strict Mode – React
A JavaScript library for building user interfaces
reactjs.org
모든 컴포넌트들에 대해서 unmount한 후 remount 되는 상황을 검사하기 위함입니다. 그래서 useEffect로 lifecycle 로직을 아래와 같이 구현한다면, mount 로직 → unmount 로직 → mount 로직이 수행됩니다.
useEffect(() => { // mount 로직 return () => { // unmount 로직 } }, []);
이때 mount 로직 부분에 외부 API 콜이 있을 때, 중복해서 불리면 안되는 경우 오류가 발생합니다. 회사에서 겪은 문제로 aws cognito에서 /oauth2/token을 다음과 같이 사용합니다.
useEffect(() => { // mount 로직 const fetch = async () => { await axios.post(`${COGNITO_DOMAIN}/oauth2/token`, ...); } fetch().catch(); return () => { // unmount 로직 } }, []);
테스트를 해보면 "invalid_grant" 오류 발생합니다.
unmount -> remount 시에 오류 발생 unmount 후 remount시에 invalid_grant aws cognito /oauth2/token 엔드포인트 문서에 정리되어있는 invalid_grant 내용을 보면 다음과 같습니다.
새로 고침 토큰이 취소되었습니다.
권한 부여 코드를 이미 사용했거나 해당 코드가 존재하지 않습니다.같은 authorization_code를 사용하여 두 번의 api 콜을 하였기 때문이라고 생각합니다. “권한 부여 코드를 이미 사용했거나…” 이 구절에 대한 해석인데, 정확한 해석인지 한 번더 고민해봐야겠습니다.
해결 방법 1: Strict Mode 안 쓰기
별로 좋지 않습니다. Strict Mode는 컴포넌트의 생명주기 검사를 해주기 때문에 안정적인 개발에 매우 유용합니다.
해결 방법 2: 요청 취소
axios “취소 토큰”을 사용하여 요청 취소를 할 수 있습니다. 컴포넌트가 unmount될 때 처음 요청을 cleanup 부분에서 취소하는 것입니다. 취소 토큰에 대한 내용은 공식 가이드로 쉽게 이해할 수 있었습니다. 이 때 주의할 점이 하나의 취소 토큰을 모두 요청의 cancelToken으로 지정하면 처음 요청과 remount시 요청이 모두 취소됩니다. 따라서 useEffect 내부에서 취소 토큰을 선언하여 요청마다 다른 취소 토큰을 사용하도록 해주어야 합니다.
useEffect(() => { const source = axios.CancelToken.source(); // mount 로직 const fetch = async () => { await axios.post(`${COGNITO_DOMAIN}/oauth2/token`, { cancelToken: source.token }); } fetch().catch((thrown) => { if (axios.isCancel(thrown) { // 의도된 cancel error } else { // 의도하지 않은 error } }); return () => { // unmount 로직 source.cancel(); } }, []);
취소된 요청은 cancel error를 throw합니다. 따라서 try catch와 axios의 isCancel을 사용하여 해당 부분의 cancel error를 처리해줍니다.
취소가 정상적으로 동작하면 사진과 같이 Network에서 canceled를 확인할 수 있습니다.
canceled된 요청 fetch를 사용하는 경우, AbortController를 사용하여 똑같이 구현할 수 있다고 합니다.
참고
https://hmos.dev/how-to-cancel-at-axios
How to cancel at axios | hmos.dev
The article that how to use cancel logic on axios request.
hmos.dev
고민
axios 요청 취소 가이드를 보면 다음과 같이 적혀있습니다.
Axios의 취소 토큰 API는 중단된 proposal-cancelable-promises을 기반으로 하고 있습니다.
“중단된” 것을 기반으로 동작한다니 굉장히 불안한 내용입니다. axios에서도 fetch와 같이 AbortController를 사용하여 처리하는 부분도 있습니다. 위 내용을 좀 더 조사해서 어떤 것을 사용해야할지 고민해봐야겠습니다.
728x90'Front-end > React' 카테고리의 다른 글
React Component debounce 적용 (1) 2023.03.05 React CRACO 설정 (0) 2023.02.09 현재 state와 동일한 값으로 업데이트해도 리렌더링되는 경우 (0) 2023.02.08 React Production 환경 테스트 (0) 2023.01.28 React Test (0) 2023.01.18