마지막으로 Effect 이후 일어나는 Cleanup Effect
에 대해서 알아보겠습니다.
Cleanup Effect
는 간단하게 설명하자면, 이전에 일으킨 Side Effect
를 정리할 필요가 있을 때 사용합니다.
앞에서 예시로 들었던 Side Effect
중 여러분이 조금 더 익숙할 이벤트 리스너 케이스를 다시 한번 살펴보겠습니다. 다음 코드는 페이지에 스크롤 이벤트가 일어날 때마다 console에 현재 스크롤이 위치한 Y 좌표를 출력합니다.
Side Effect
이므로 useEffect
안에서 사용하고, 이벤트 리스너는 한번만 등록하면 되기 때문에 의존성 배열에는 빈 배열을 넣어주었습니다.
useEffect(() => {
function handleScroll() {
console.log(window.scrollY)
}
document.addEventListener("scroll", handleScroll)
}, [])
하지만 우리가 이 페이지를 벗어났을 때 이 이벤트 리스너는 더 이상 필요없어질 수 있습니다. 이 경우 우리가 일으켰던 Effect를 정리해줘야 합니다. 이 때마다 Cleanup Effect를 일으킬 수 있도록 useEffect 안에 해당 로직을 정리하는 동작을 정의해두면 됩니다. 아래 코드에서 하이라이트 해둔 부분처럼 말이죠.
useEffect(() => {
function handleScroll() {
console.log(window.scrollY)
}
document.addEventListener("scroll", handleScroll)
return () => {
document.removeEventLisnter("scroll", handleScroll)
}
}, [])
주의할 점은 단순히 컴포넌트가 생성되고, 사라지는 시점에만 Cleanup Effect가 실행되는 건 아니라는 겁니다. 다음 Effect가 일어나기 전에, 이전 Effect의 영향을 정리해줘야 한다는 컨셉을 꼭 기억해주세요.
다음 예시 코드는 state가 업데이트 될 때마다 Effect를 일으키고, 다음 Effect가 일어나기 전에 Cleanup Effect를 일으킵니다.
const App = () => {
const [count, setCount] = useState(0);
console.log("render", count);
useEffect(() => {
console.log("useEffect Callback", count);
return () => {
console.log("cleanUp", count);
});
}, [count]);
return <div onClick={() => setCount(count + 1)}>하잉</div>;
};
export default Foo;
render, 0
useEffect Callback, 0
// 클릭
render, 1
cleanUp, 0
useEffect Callback, 1
다이어그램을 통해 다시 한번 Effect의 순서를 확인하면서 설명을 마무리하겠습니다.
Render
와 Clean Up
, Effect
사이의 관계를 주의 깊게 살펴주세요.