
useEffect에서 clean-up을 사용하는 이유React에서 'useEffect' 후크의 clean-up 기능은 메모리 누수를 방지하고 구성 요소를 마운트 해제할 때 또는 업데이트된 종속성을 사용하여 구성 요소를 다시 렌더링하기 전에 더 이상 필요하지 않은 부작용을 제거하는 데 중요합니다. 이 기능을 사용하면 애플리케이션이 효율적으로 실행되고 타이머, 구독 또는 이벤트 리스너와 같은 리소스가 적절하게 관리됩니다.
useEffect의 clean-up는 다음 용도로 사용됩니다.
useEffect 내부에 함수를 선언하면 선택적으로 다른 함수를 반환할 수 있습니다. 이 반환된 함수는 정리 함수입니다. React는 다음과 같은 경우에 이 clean-up 기능을 실행합니다.
이벤트 리스너를 설정하지만 clean-up하지는 않는 구성 요소를 생각해 보세요. 구성 요소가 마운트 해제된 후에도 리스너가 계속 활성 상태인 경우 오류나 예기치 않은 동작이 발생할 수 있습니다.
import React, { useState, useEffect } from 'react';
function ExampleComponent() {
const [windowWidth, setWindowWidth] = useState(window.innerWidth);
useEffect(() => {
const handleResize = () => {
setWindowWidth(window.innerWidth);
};
window.addEventListener('resize', handleResize);
// No clean-up here
}, []); // The effect runs only on mount
return <div>Window width: {windowWidth}</div>;
}
이 예에서는 구성요소가 마운트될 때 'handleResize'가 이벤트 리스너로 추가됩니다. 그러나 구성 요소가 마운트 해제되면 이벤트 리스너는 제거되지 않습니다. 구성 요소 인스턴스가 DOM에서 제거되면 이벤트 핸들러는 여전히 존재하지 않는 구성 요소의 상태를 업데이트하려고 시도하므로 오류가 발생할 수 있습니다.
이벤트 리스너를 제거하기 위해 clean-up를 구현하는 방법은 다음과 같습니다.
import React, { useState, useEffect } from 'react';
function ExampleComponent() {
const [windowWidth, setWindowWidth] = useState(window.innerWidth);
useEffect(() => {
const handleResize = () => {
setWindowWidth(window.innerWidth);
};
window.addEventListener('resize', handleResize);
// Clean-up function
return () => {
window.removeEventListener('resize', handleResize);
};
}, []); // The effect runs only on mount
return <div>Window width: {windowWidth}</div>;
}
이 수정된 예에서 clean-up 함수는 구성 요소가 마운트 해제될 때 또는 효과가 다시 실행되기 전에 이벤트 리스너를 제거합니다(이 경우 종속성 배열이 비어 있기 때문에 발생하지 않습니다). 이렇게 하면 구성 요소가 마운트 해제된 후 상태를 업데이트하려고 시도하는 것을 방지하여 잠재적인 메모리 누수 및 오류를 방지할 수 있습니다.

리소스를 효율적으로 관리하는 강력한 React 구성 요소를 작성하려면 useEffect에서 정리 기능을 사용하는 것이 필수적입니다. 이는 메모리 누수를 방지하는 데 도움이 되며 구성 요소가 오래된 DOM 요소 또는 데이터와 상호 작용하지 않도록 합니다.
처음 clean-up에 대한 설명을 보았을 때, 아 좋은 기능인 것을 알겠는데 결과가 동일하게 나오는데… 도대체 무슨 효과가 있는 것인가에 대한 생각이 많이 들었다.
근데, 이러한 경우 효과가 있겠구나를 많이 생각하게 됐다.
위 코드 예시에서 handleResize 이벤트가 존재한다. 이 이벤트가 존재하는 화면명이 A라고 하자.
A에서 B라는 화면으로 넘어갈 때, clean-up 기능이 있을 경우 아무 문제가 없다. 하지만, clean-up 기능이 없다면?
B 화면으로 넘어가도 handleResize 이벤트가 리스너에 남아 있을 수도 있다. 그럴 경우, B 안에서는 handleResize 가 없지만, 리스너 자체에는 handleResize 가 남아 있는 상태가 발생할 수도 있다. 즉, A 화면이 아님에도 불구하고 handleResize 가 돌아가고 있을 수도 있다는 것. 이러한 상태에서는 에러가 발생할 수 있다.
따라서, useEffect 안에서 clean-up을 사용해 에러가 발생하지 않도록 하는 것이 오늘 배움의 key-point라고 할 수 있다.