[React] React.js 강좌 4. 컴포넌트 생명주기 (Lifecycle Methods)
1. 생명주기(Lifecycle)란?
리액트에서 컴포넌트는 생성되고, 업데이트되고, 사라지는 흐름을 가지고 있습니다.
이 과정을 **컴포넌트의 생명주기(Lifecycle)**라고 부릅니다.
쉽게 말하면, 리액트 컴포넌트도 사람처럼
“태어남 → 변화함 → 사라짐”의 과정을 겪는다는 뜻입니다.
이 생명주기를 이해하면 다음과 같은 일들을 더 효율적으로 처리할 수 있습니다.
- API 데이터를 컴포넌트가 처음 렌더링될 때 불러오기
- 특정 상태가 바뀔 때만 실행되는 로직 제어
- 컴포넌트가 사라질 때 정리(clean-up) 작업 수행
2. 클래스형 컴포넌트의 생명주기 메서드
리액트 초창기에는 클래스형 컴포넌트에서 생명주기 메서드를 사용했습니다.
아래 코드는 기본적인 구조를 보여줍니다.
import React, { Component } from 'react';
class Example extends Component {
constructor(props) {
super(props);
this.state = { count: 0 };
console.log('1️⃣ constructor 실행');
}
componentDidMount() {
console.log('3️⃣ componentDidMount - 컴포넌트가 화면에 나타남');
}
componentDidUpdate() {
console.log('4️⃣ componentDidUpdate - 상태나 props가 변경됨');
}
componentWillUnmount() {
console.log('5️⃣ componentWillUnmount - 컴포넌트가 사라짐');
}
render() {
console.log('2️⃣ render 실행');
return (
<div>
<p>현재 카운트: {this.state.count}</p>
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
+1
</button>
</div>
);
}
}
export default Example;
위 코드를 실행하면 콘솔에는 다음 순서로 출력됩니다.
1️⃣ constructor 실행
2️⃣ render 실행
3️⃣ componentDidMount - 컴포넌트가 화면에 나타남
버튼을 눌러 상태가 바뀌면:
2️⃣ render 실행
4️⃣ componentDidUpdate - 상태나 props가 변경됨
그리고 컴포넌트가 화면에서 사라질 때:
5️⃣ componentWillUnmount - 컴포넌트가 사라짐
이렇게 리액트는 컴포넌트의 생명주기에 따라 자동으로 특정 메서드를 호출합니다.
3. 주요 생명주기 메서드 정리
단계 메서드 설명
| 마운트(Mount) | constructor, componentDidMount | 컴포넌트가 처음 생성되어 DOM에 부착될 때 |
| 업데이트(Update) | componentDidUpdate | props나 state가 바뀌어 다시 렌더링될 때 |
| 언마운트(Unmount) | componentWillUnmount | 컴포넌트가 화면에서 제거될 때 |
이 흐름을 이해하면 “언제 데이터를 가져오고”, “언제 정리할지”를 명확히 제어할 수 있습니다.
4. 함수형 컴포넌트에서의 생명주기 – useEffect
리액트 16.8 이후부터는 Hooks를 통해 함수형 컴포넌트에서도 생명주기를 제어할 수 있습니다.
이때 사용하는 것이 바로 useEffect 훅입니다.
import React, { useState, useEffect } from 'react';
function Counter() {
const [count, setCount] = useState(0);
// 마운트 및 업데이트 시 실행
useEffect(() => {
console.log('렌더링 이후 실행됨');
});
return (
<div>
<p>현재 카운트: {count}</p>
<button onClick={() => setCount(count + 1)}>+1</button>
</div>
);
}
export default Counter;
useEffect는 기본적으로 렌더링 후마다 실행됩니다.
하지만 두 번째 인자로 **의존성 배열(dependency array)**을 전달하면
언제 실행할지를 세밀하게 제어할 수 있습니다.
5. useEffect의 세 가지 사용 패턴
① 마운트될 때 한 번만 실행
useEffect(() => {
console.log('처음 한 번만 실행');
}, []);
의존성 배열이 []이면 처음 렌더링될 때 한 번만 실행됩니다.
보통 API 호출이나 초기 설정에 사용됩니다.
② 특정 값이 바뀔 때만 실행
useEffect(() => {
console.log('count가 바뀔 때만 실행');
}, [count]);
이 경우 count 값이 변경될 때만 실행됩니다.
이를 통해 불필요한 렌더링 로직을 방지할 수 있습니다.
③ 언마운트 시 정리(clean-up)
useEffect(() => {
const timer = setInterval(() => {
console.log('1초마다 실행');
}, 1000);
return () => {
clearInterval(timer);
console.log('컴포넌트가 사라질 때 정리');
};
}, []);
useEffect에서 return을 사용하면
컴포넌트가 사라질 때(clean-up) 실행할 코드를 정의할 수 있습니다.
이는 componentWillUnmount와 동일한 역할을 합니다.
6. 클래스형 vs 함수형 생명주기 비교
기능 클래스형 함수형(Hooks)
| 마운트 시 | componentDidMount() | useEffect(() => {...}, []) |
| 업데이트 시 | componentDidUpdate() | useEffect(() => {...}, [state]) |
| 언마운트 시 | componentWillUnmount() | useEffect(() => { return () => {...} }) |
지금은 함수형 컴포넌트가 주류이기 때문에
대부분의 프로젝트에서는 useEffect 하나로 생명주기를 모두 제어합니다.
7. 마무리 정리
- 리액트 컴포넌트는 “생성 → 업데이트 → 소멸”의 흐름을 가진다.
- 클래스형에서는 componentDidMount, componentDidUpdate, componentWillUnmount로 제어한다.
- 함수형에서는 useEffect 훅 하나로 생명주기를 모두 처리할 수 있다.
- 클린업(clean-up)을 적절히 사용하면 메모리 누수를 방지할 수 있다.
다음 글에서는 리액트에서 자주 사용하는 **이벤트 처리(Event Handling)**와
this 바인딩의 원리에 대해 알아보겠습니다.