리액트 컴포넌트는 마치 살아있는 존재처럼 생명 주기(Lifecycle)를 갖는다. 컴포넌트가 생성되어 화면에 표시되고(탄생), 상태 변화에 따라 업데이트되며(변화), 마지막으로 화면에서 사라지는(소멸) 일련의 과정을 거친다. 이 흐름을 이해하는 것은 리액트 개발의 기본이자 핵심이다.
과거에는 클래스형 컴포넌트에서 명시적인 생명 주기 메서드를 사용했지만, 현재는 함수형 컴포넌트와 useEffect
Hook을 통해 이를 더 간결하고 유연하게 다룬다.
클래스형 컴포넌트는 각 단계별로 특정 메서드가 순차적으로 호출된다. 주요 단계는 다음과 같다.
컴포넌트가 처음 생성되어 DOM에 삽입될 때 발생한다.
constructor()
this.state
초기화 및 메서드 바인딩을 수행한다.render()
componentDidMount()
컴포넌트의 props
또는 state
가 변경될 때 리렌더링 과정을 거친다.
shouldComponentUpdate(nextProps, nextState)
true
(기본값) 반환 시 리렌더링, false
반환 시 중단.render()
props
나 state
를 기반으로 UI를 다시 렌더링한다.componentDidUpdate(prevProps, prevState)
props
/state
와 현재 값을 비교하여 조건부 로직 수행 (예: 특정 조건 만족 시 추가 API 요청).컴포넌트가 DOM에서 제거될 때 발생한다.
componentWillUnmount()
componentDidMount
에서 등록한 이벤트 리스너, 타이머, 구독 등을 해제하는 정리(cleanup) 작업. 메모리 누수 방지에 필수적이다.useEffect
Hook함수형 컴포넌트는 useEffect
Hook을 사용하여 클래스형 컴포넌트의 생명 주기 기능 대부분을 구현한다. useEffect
는 렌더링 이후에 부수 효과(side effects)를 실행한다.
기본 구조: useEffect(callback, [dependencies])
callback
: 실행할 함수.dependencies
(의존성 배열): 배열 안의 값이 변경될 때만 callback
함수가 재실행된다.useEffect
로 생명 주기 흉내 내기마운트 시 (componentDidMount
대체)
[]
)로 전달하면, 컴포넌트가 처음 렌더링될 때 한 번만 실행된다.import React, { useEffect } from 'react';
function MyComponent() {
useEffect(() => {
console.log('컴포넌트 마운트됨!');
// API 호출 등
}, []); // 빈 배열: 마운트 시에만 실행
return <div>내 컴포넌트</div>;
}
업데이트 시 (componentDidUpdate
대체)
[value]
)을 전달하면, 해당 값이 변경될 때마다 실행된다.import React, { useState, useEffect } from 'react';
function Counter() {
const [count, setCount] = useState(0);
useEffect(() => {
console.log(`count가 ${count}(으)로 변경됨!`);
// count 변경 시 수행할 작업
}, [count]); // count가 변경될 때마다 실행
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>증가</button>
</div>
);
}
언마운트 시 (componentWillUnmount
대체) - 정리(Cleanup) 함수
useEffect
의 콜백 함수에서 정리 함수(cleanup function)를 반환하면, 해당 함수는 컴포넌트가 언마운트되기 직전 또는 다음 effect
가 실행되기 전에 호출된다.import React, { useState, useEffect } from 'react';
function TimerComponent() {
useEffect(() => {
const timerId = setInterval(() => {
console.log('타이머 동작 중...');
}, 1000);
// 정리 함수
return () => {
clearInterval(timerId);
console.log('타이머 정리됨! (언마운트 또는 다음 effect 실행 전)');
};
}, []); // 마운트 시 타이머 설정, 언마운트 시 타이머 정리
return <div>타이머 컴포넌트</div>;
}
리액트 컴포넌트의 생명 주기를 이해하는 것은 컴포넌트의 동작을 예측하고, 상태 변화에 따른 적절한 작업을 수행하며, 애플리케이션의 성능을 최적화하는 데 매우 중요하다.
최신 리액트 개발에서는 함수형 컴포넌트와 useEffect
Hook을 사용하는 것이 권장된다. 이를 통해 더욱 간결하고 직관적으로 컴포넌트의 생명 주기를 관리할 수 있다.
React - props 전달 방식의 차이: `{...todo}` vs `todo={todo}` (0) | 2025.06.05 |
---|---|
React - useEffect를 이용한 컴포넌트 라이프사이클 제어 정리 (1) | 2025.06.05 |
React - 상태 끌어올리기(State Lifting) (0) | 2025.06.01 |
React - Hook 사용 규칙과 Custom Hook 예제 (0) | 2025.06.01 |
React - Hooks (1) | 2025.06.01 |