렌더링이란 컴포넌트가 화면에 그려지는 과정을 말합니다.
React에서는 JSX로 작성한 컴포넌트가 브라우저의 DOM에 실제 요소로 변환되는 것을 렌더링이라고 합니다.
렌더링은 다음의 두 가지 경우에 발생합니다:
렌더링은 단순히 "화면에 그린다"라는 행위에 가까우며, 컴포넌트의 상태가 변경될 때마다 발생할 수 있습니다.
마운트는 컴포넌트가 처음 DOM에 추가되는 과정을 의미합니다.
마운트 시점은 컴포넌트의 초기 렌더링이 일어날 때와 정확히 일치합니다.
마운트는 단 한 번만 발생하며, 이때 컴포넌트의 초기 설정
(이벤트 리스너 등록, 데이터 fetch 등)을 진행합니다.
마운트는 초기 렌더링 시점에만 발생하며,
처음 컴포넌트가 DOM에 추가되는 순간을 의미합니다.
렌더링은 마운트를 포함하는 더 넓은 개념으로,
초기 렌더링뿐만 아니라 업데이트가 발생할 때마다 재실행됩니다.
즉, 마운트와 렌더링은 관련은 있지만, 마운트는 렌더링의 한 부분이며
초기 렌더링 시점에 한정된 개념입니다.
언마운트(Unmount)는 React에서 컴포넌트가 DOM에서 제거되는 과정을 의미합니다. 쉽게 말해, 컴포넌트가 화면에서 사라지는 시점을 말합니다. 언마운트가 발생하면 해당 컴포넌트와 관련된 모든 데이터와 이벤트, 비동기 작업 등을 정리하여 메모리 누수를 방지하고, 더 이상 사용되지 않는 리소스를 해제하는 것이 중요합니다.
언마운트가 발생하는 대표적인 경우는 다음과 같습니다:
예를 들어, 상태 값에 따라 특정 컴포넌트를 조건부로 렌더링하다가, 조건이 변해서 해당 컴포넌트가 더 이상 화면에 표시되지 않을 때.
{showComponent && <MyComponent />}
위 코드에서 showComponent가 false가 되면 는 DOM에서 제거됩니다. 이때가 언마운트 시점입니다.
부모 컴포넌트가 언마운트되면 그 안에 포함된 모든 자식 컴포넌트들도 함께 언마운트됩니다.
React Router와 같은 라이브러리를 사용하여 페이지 간 이동을 할 때, 현재 페이지에 있는 컴포넌트들이 사라지고 새로운 페이지의 컴포넌트들이 마운트됩니다.
컴포넌트가 직접적으로 제거될 때
특정 컴포넌트를 강제로 DOM에서 제거할 때
(예: ReactDOM.unmountComponentAtNode 사용).
언마운트가 발생하면, 컴포넌트는 더 이상 화면에 존재하지 않으므로 clean-up 작업을 통해 메모리 누수와 불필요한 동작을 방지해야 합니다. 대표적인 clean-up 작업은 다음과 같습니다:
컴포넌트가 마운트될 때 등록한 이벤트 리스너를 제거하지 않으면, 컴포넌트가 사라져도 해당 리스너가 계속 동작하여 메모리 누수가 발생할 수 있습니다.
useEffect(() => {
window.addEventListener("resize", handleResize);
return () => {
window.removeEventListener("resize", handleResize);
};
}, []);
setInterval이나 setTimeout으로 설정된 타이머를 제거하지 않으면 컴포넌트가 언마운트된 후에도 타이머가 계속 실행됩니다.
useEffect(() => {
const timer = setInterval(() => {
console.log("타이머 동작 중");
}, 1000);
return () => {
clearInterval(timer); // 타이머 정리
};
}, []);
컴포넌트가 언마운트된 후에도 비동기 요청이 완료되면, 상태 업데이트가 발생하여 오류를 유발할 수 있습니다. 따라서 요청을 취소하거나 상태 업데이트를 방지해야 합니다.
컴포넌트가 DOM에서 제거되면 Ref로 연결된 요소도 사라지기 때문에, 필요하다면 해당 Ref를 초기화합니다.
useEffect의 clean-up 함수는 언마운트 시점에서 호출됩니다. 다음과 같은 형태로 작성됩니다:
useEffect(() => {
// 마운트 시 실행할 로직 (set up)
console.log("컴포넌트가 마운트되었습니다.");
return () => {
// 언마운트 시 실행할 로직 (clean up)
console.log("컴포넌트가 언마운트되었습니다.");
};
}, []);
위 코드는 컴포넌트가 처음 마운트될 때 console.log("컴포넌트가 마운트되었습니다.");를 실행하고, 언마운트될 때 console.log("컴포넌트가 언마운트되었습니다.");를 실행합니다.
마운트: 컴포넌트가 처음 DOM에 추가되며, useEffect의 콜백 함수가 실행(set up).
업데이트: 의존성 배열의 값이 변경될 때마다 useEffect의 clean-up 함수가 먼저 호출되고, 이후 새로운 set up 함수가 실행.
언마운트: 컴포넌트가 DOM에서 제거되기 전에 useEffect의 clean-up 함수가 호출됨.
따라서 언마운트는 컴포넌트가 더 이상 화면에 존재하지 않게 되기 전에 정리 작업을 수행하는 마지막 시점을 말한다고 이해할 수 있습니다.
의존성 배열이 변경될 때 useEffect가 재실행되더라도, 컴포넌트 전체가 언마운트되고 다시 마운트되는 것은 아닙니다. 이를 이해하려면, useEffect의 clean-up 함수와 마운트/언마운트의 관계를 구분할 필요가 있습니다.
의존성 배열이 변경될 때 useEffect가 어떻게 동작하는지 순서대로 설명하면 다음과 같습니다.
위 과정에서 일어나는 것은 clean-up 함수가 호출된 것일 뿐,
컴포넌트 전체의 언마운트가 아닙니다.
컴포넌트가 언마운트되려면 실제로 DOM에서 제거되어야 하고,
그 시점에 useEffect의 clean-up 함수가 호출된 후,
컴포넌트가 메모리에서 사라져야 합니다.
반면, 의존성 배열이 변경될 때 호출되는 clean-up 함수는
기존 effect를 정리하고 새로운 effect를 실행하기 위한 준비 작업입니다.
컴포넌트는 여전히 DOM에 남아 있으며 단지 useEffect가 갱신되는 것입니다.