useEffect 클린업(cleanup) 함수
🍑 useEffect
React에서 부수 효과를 수행할 수 있게 해주는 Hook이다.
렌더링 이후에 실행된다.
useEffect(() => {
// 부수 효과 로직
}, [의존성]);
🍑 cleanup 함수
useEffect 내부에서 return () => {} 형태로 작성하는 함수를 cleanup 함수라고 한다.
타이머나 이벤트를 등록한 뒤 정리하지 않으면 메모리 누수나 중복 실행이 발생할 수 있기 때문에,
보통 컴포넌트가 사라질 때나 effect가 다시 실행되기 전 정리 작업을 수행하기 위해 사용된다.
🍑 useEffect 실행 시점
렌더링 (가상 DOM 계산)
↓
커밋 (DOM 업데이트 완료)
↓
useEffect 실행 💎
즉, 화면이 실제로 브라우저에 렌더링 된 후에 실행된다.
🍑 cleanup 함수 실행 시점
useEffect의 의존성 배열의 값이 변경되면
cleanup 함수를 먼저 실행시킨 뒤, 새로운 effect를 실행한다.
📘 case 1) 의존성 배열이 없는 경우 ([])
useEffect(() => {
console.log("🍏 effect 실행");
return () => {
console.log("🍎 cleanup 실행");
};
}, []);
마운트 | 🍏 effect 실행 |
언마운트 | 🍎 cleanup 실행 |
앞서 실행 순서를 설명하면서 cleanup 함수를 먼저 실행시킨 뒤에 effect를 실행한다고 했는데,
이건 의존성 값이 변경되었을 때 해당하는 내용이다.
처음 마운트될 때는 정리할 것이 없기 때문에 바로 effect를 실행하고, 언마운트 시 cleanup을 실행한다.
📘 case 2) 의존성 배열에 값이 있는 경우
useEffect(() => {
console.log("🍏 effect 실행:", age);
return () => {
console.log("🍎 cleanup 실행:", age);
};
}, [age]);
마운트 (age = 20) | 🍏 effect 실행: 20 |
age = 21 변경 | 🍎 cleanup 실행: 20 → 🍏 effect 실행: 21 |
age = 22 변경 | 🍎 cleanup 실행: 21 → 🍏 effect 실행: 22 |
언마운트 | 🍎 cleanup 실행: 22 |
값이 바뀔 때마다 cleanup을 먼저 실행한 뒤 새 effect를 실행한다.
🍑 사용 예시
cleanup 함수는 외부와 연결된 작업에서 주로 사용된다.
이런 작업들은 컴포넌트가 사라졌다고 해서 자동으로 종료되지 않기 때문에, 명시적으로 정리해줘야 한다.
🕒 [ 타이머 제거 ]
useEffect(() => {
const id = setInterval(() => {
console.log('meowww');
}, 1000);
return () => clearInterval(id);
}, []);
👉🏻 [ 이벤트 리스너 제거 ]
useEffect(() => {
const handleScroll = () => console.log('scrolling');
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
}, []);
🌐 [ 웹소켓 정리 ]
useEffect(() => {
const socket = new WebSocket('https://hungry.com');
socket.onmessage = (e) => console.log(e.data);
return () => socket.close();
}, []);
🍑 정리
코드만 봤을 때는 effect를 실행하고,
useEffect를 종료하기 직전에 cleanup 함수를 실행할 것 같았는데 예상과 다르게 동작한다는 것을 알게 되었다.
cleanup 함수는 새로운 값을 업데이트하기 전에 이전 값을 정리해주는 역할을 한다고 생각하면 될 것 같다.