리액트에서 "라이프사이클(Lifecycle)"은 컴포넌트가 생성되고, 업데이트되고, 제거되는 과정을 의미합니다. 이 흐름을 잘 이해하면 상태 관리, API 호출, 정리(cleanup) 작업, 퍼포먼스 최적화에 능숙해질 수 있습니다.
라이프사이클이란?
리액트 컴포넌트는 다음 3단계를 거칩니다:
- 마운트(Mount): 컴포넌트가 DOM에 처음 생성될 때
- 업데이트(Update): 상태나 props가 변경되어 리렌더링 될 때
- 언마운트(Unmount): 컴포넌트가 DOM에서 제거될 때
각 단계에서 특정 코드를 실행할 수 있는 라이프사이클 메서드 또는 훅이 존재합니다.
클래스형 컴포넌트의 라이프사이클 메서드
클래스형 컴포넌트에서는 다음과 같은 메서드가 사용됩니다:
마운트 시 실행
componentDidMount() {
// 컴포넌트가 DOM에 삽입됨
// 예: API 호출, 타이머 설정
}
업데이트 시 실행
componentDidUpdate(prevProps, prevState) {
// 이전 props/state와 비교 가능
}
언마운트 시 실행
componentWillUnmount() {
// 정리 작업 (타이머 해제, 이벤트 제거 등)
}
⚠️ 참고:
componentWillMount
,componentWillReceiveProps
,componentWillUpdate
는 현재 폐기(deprecated) 상태입니다.
함수형 컴포넌트의 useEffect
함수형 컴포넌트에서는 useEffect
훅 하나로 모든 라이프사이클을 대체할 수 있습니다.
기본 문법
useEffect(() => {
// 마운트 시 실행
return () => {
// 언마운트 시 실행 (cleanup)
};
}, []);
업데이트 시 실행
useEffect(() => {
// 특정 값이 바뀔 때 실행됨
}, [someState]);
[someState]
가 변경될 때만 실행되므로 퍼포먼스 최적화에 매우 중요합니다.
의존성 배열(Dependency Array)의 의미
의존성 배열 | 동작 |
없음 | 매 렌더링마다 실행 |
[] | 한 번만 실행 (마운트) |
[state] | 해당 state가 바뀔 때만 실행 |
예시
useEffect(() => {
console.log("매 렌더링마다 실행됨");
});
useEffect(() => {
console.log("마운트 시 한 번만 실행됨");
}, []);
useEffect(() => {
console.log("state가 바뀔 때 실행됨");
}, [state]);
정리 함수 (Cleanup)
리액트에서는 리소스 누수를 막기 위해 컴포넌트가 언마운트되거나 다시 실행되기 전 정리(cleanup) 작업이 필요합니다.
useEffect(() => {
const id = setInterval(() => console.log("tick"), 1000);
return () => {
clearInterval(id); // 정리
};
}, []);
클래스 vs 함수형 예시 비교
클래스형
class Timer extends React.Component {
componentDidMount() {
this.interval = setInterval(() => console.log("tick"), 1000);
}
componentWillUnmount() {
clearInterval(this.interval);
}
render() {
return <div>타이머</div>;
}
}
함수형
function Timer() {
useEffect(() => {
const id = setInterval(() => console.log("tick"), 1000);
return () => clearInterval(id);
}, []);
return <div>타이머</div>;
}
주의할 점과 팁
useEffect
는 비동기 함수(async)를 직접 받을 수 없음 → 내부에서 async 함수를 선언해야 함- 함수형 컴포넌트의
useEffect
는 렌더링 이후 실행 useLayoutEffect
는 DOM 조작이 필요한 경우 먼저 실행됨 (주의해서 사용)
마무리 요약
상황 | 클래스형 | 함수형 |
마운트 시 | componentDidMount | useEffect(..., []) |
업데이트 시 | componentDidUpdate | useEffect(..., [dep]) |
언마운트 시 | componentWillUnmount | return () => {} (useEffect 안쪽) |
리액트의 라이프사이클 흐름을 이해하면 API 호출 타이밍, 메모리 누수 방지, 퍼포먼스 튜닝 등을 안정적으로 구현할 수 있습니다.
728x90