요즘 웹 개발에서 api를 패치하는 비동기 작동을 다루는 것은 흔한 일이고 나도 프로젝트에 당연하게 사용하고 있다. 그런데, 이 행위는 생각보다 오래 걸리고 예기치 못한 이슈를 발생시키면서 불필요한 메모리를 잡아먹기도 한다. 이때 필요한 것이 바로 자바스크립트의 기능 중 하나인 AbortController이다. 특히 React의 useEffect 훅과 사용할 때 굉장히 유용하다.
AbortController란?
abort는 '중단하다'라는 뜻으로, 이전 요청을 취소하는 취소하는 역할을 한다.
AbortController을 fetch할 때 사용할 때의 장점
1. 효율적인 리소스 관리
한 api가 완료되는데 오래 걸릴때, 그 요청을 취소함으로써 불필요한 메모리 소비를 막을 수 있다.
2. 빠른 유저 경험
만약 유저가 여러개의 api 요청을 보내는 것을 시작해놓고, 다른 페이지로 이동하거나 다른 액션을 할 때, 이미 시작된 요청을 중지시킬 수 있다. 그러면 더이상 필요하지 않은 그 일을 그만두고 유저의 그 다른 액션에 더 빠르게 반응할 수 있다.
3. 경쟁 상태(race condition) 방지
useEffect 내부에서 state를 결과에 따라 업데이트하는 로직이 있다고 가정해보자. 만약, 비동기 함수가 useEffect의 인수로 사용가능하다면 그 함수의 응답 속도에 따라 결과가 이상하게 나타날 수 있다. 극단적인 예로, 이전 state기반 응답이 10초가 걸렸고, 이후 바뀐 state 기반 응답이 1초 뒤에 왔다면 이전 state 기반으로 결과가 나와버릴 수가 있다. 이러한 문제를 useEffect의 경쟁 상태라고한다.
4. 에러 핸들링
만약 AbortController을 사용해서 api를 취소했을 경우, AbortError를 이용해 그 에러를 다룰 수 있다.
5. 확장성 및 성능 최적화
많은 컴포넌트들과 복잡한 어플리케이션을 가지고 있다면, 비동기 api 요철을 관리하는 것이 매우 중요하다. AbortController로 요청 취소, 클린업 함수, 메모리 누수, 불필요한 리소스 사용을 처리할 수 있다.
아래는 useEffect안에서 AbortConroller를 사용한 예시이다. 내가 자주 쓰는 fetch 형식으로 적용해 보았다.
import React, { useEffect } from 'react';
const MyComponent = () => {
useEffect(() => {
const controller = new AbortController();
const signal = controller.signal;
// useEffect 내부에 fetchData 함수 정의
const fetchData = async () => {
try {
const res = await fetch('http://fetch.data.com', { signal });
const result = await res.json();
console.log(result);
} catch (error) {
if (error.name === 'AbortError') {
console.log('Fetch aborted');
} else {
console.log('Fetch error:', error);
}
}
};
fetchData();
// 클린업 함수
return () => {
controller.abort();
};
}, []);
return <div> My Component</div>
};
export default MyComponent;
이때, 클린업 함수는 함수형 컴포넌트가 리랜더링됐을 때, 의존성 변화가 있었을 당시의 이전 상태를 청소해주는 개념으로 보면 된다.
비동기 함수가 useEffect 내부에 존재하게 되면 useEffect 내부에서 비동기 함수가 생성되고 실행되는 것을 반복함으로 클린업 함수에서 이전 비동기 함수에 대한 처리를 추가하는 것이 좋다. 이렇게 함으로써, 성능을 최적화하고 더 매끄러운 UX를 제공할 수 있다.
[참고] https://www.j-labs.pl/en/tech-blog/how-to-use-the-useeffect-hook-with-the-abortcontroller/
[참고] 모던 리액트 딥다이브 도서
'Study > 모던 리액트 Deep Dive' 카테고리의 다른 글
creacte-next-app 없이 next.js 구축하기 (0) | 2024.04.25 |
---|---|
서버 사이드 렌더링이란? | with Next.js (0) | 2024.03.22 |
[2주차] 클로저,이벤트 루프와 비동기 통신의 이해 p.59-79 | 모던 리액트 딥다이브 (0) | 2024.02.20 |
[1주차] 자바스크립트의 동등 비교, 함수, 클래스 | 모던 리액트 딥다이브 공부 (0) | 2024.02.15 |