회사에서 NextJS 프로젝트를 하면서 useEffect hook에서 BFF 에 호출하는 로직을 추가했다.
function useAxiosCall<T>(apiUrl: string) {
const [data, setData] = useState<T | null>(null);
useEffect(()=>{
Axios.get<T>(apiUrl).then(res => {
setData(res.data);
});
}, []);
}
해당 axios 호출에서 예외가 발생하는 경우가 있었고, 익숙하듯 try...catch 문으로 감싸줘 봤다.
function useAxiosCall<T>(apiUrl: string) {
const [data, setData] = useState<T | null>(null);
useEffect(()=>{
try{
Axios.get<T>(apiUrl).then(res => {
setData(res.data);
});
}catch(e){
/** 에러처리 로직 */
}
}, []);
}
하지만 try...catch 문은 예외를 catch하지 못 했고, Axios 가 제공하는 Catch 메서드를 이용하니 예외를 잘 catch 했다.
function useAxiosCall<T>(apiUrl: string) {
const [data, setData] = useState<T | null>(null);
useEffect(()=>{
Axios.get<T>(apiUrl).then(res => {
setData(res.data);
}).catch((e)=>{/** 에러처리 로직 */});
}, []);
}
이유가 뭔고 하니...Axios.get 은 비동기 함수이기 때문인데,(이건 누구나 다 아는 사실이지만 간과한 것 같다.)
Axios.get 의 처리는 Web API 에서 하게 되는 동시에 Axios.get 이후 로직이 실행되고(여기선 이후 로직이 없다.) try...catch 문을 벗어난다.
결과적으론, 런타임에선 Axios.get 의 에러 발생 시점이 try...catch 문이 끝난 이후 이기에 위와 같은 현상이 벌어졌던 것이다.
해결 방법으론 아래와 같이 Axios.get 에 await 키워드를 적용해 예외가 발생해도 try...catch 문 내에서 발생하도록 동기화를 시켜주는 것이다.
function useAxiosCall<T>(apiUrl: string) {
const [data, setData] = useState<T | null>(null);
useEffect(()=>{
// useEffect 엔 비동기 함수를 Callback 으로 전달할 수 없기에
// 콜백함수 내에서 비동기 함수를 선언하자 마자 실행하도록 한다.
// try...catch 로 감싸주는 것 또한 해당 비동기 함수 내에서 한다.
(async function callApi(){
try{
await Axios.get<T>(apiUrl).then(res => {
setData(res.data);
});
// 물론 아래와 같이 해도 결과는 동일하다.
/**
const res = await Axios.get<T>(apiUrl);
setData(res.data);
*/
}catch(e){
/** 예외처리 로직 */
}
})();
}, []);
}
Javascript의 비동기 처리는 항상 쉽지 않다. (비동기가 기본적인 동작이라..)
'소프트웨어 엔지니어링 > 프론트 엔드' 카테고리의 다른 글
상태관리 라이브러리 비교 (0) | 2023.10.15 |
---|---|
react-query : cache, refetch, interval, observer (0) | 2023.03.04 |
vscode 에서 react 프로젝트 새로 셋팅하기 (0) | 2023.02.03 |
[원티드1월챌린지] FE 프리온보딩(React-Query) 종료후 과제 보충 (0) | 2023.01.25 |
[원티드1월챌린지] FE 프리온보딩(React-Query) 후기 (0) | 2023.01.20 |