리액트의 컴포넌트 라이프사이클: Hooks와 클래스 컴포넌트 비교
- 공유 링크 만들기
- X
- 이메일
- 기타 앱
리액트(React)에서 컴포넌트 라이프사이클은 컴포넌트가 생성, 업데이트, 제거되는 과정에서 특정 시점에 실행되는 메서드나 함수를 의미합니다. 리액트는 두 가지 주요 방식으로 컴포넌트를 정의할 수 있습니다: 클래스 컴포넌트와 함수형 컴포넌트(Hooks를 사용). 이 글에서는 리액트 컴포넌트 라이프사이클의 기본 개념을 설명하고, 클래스 컴포넌트와 함수형 컴포넌트(Hooks 기반)의 차이점을 비교해보겠습니다.
컴포넌트 라이프사이클이란?
컴포넌트 라이프사이클은 컴포넌트의 수명 주기 동안 발생하는 일련의 단계를 의미합니다. 이 주기는 크게 세 가지 주요 단계로 나눌 수 있습니다:
- 마운트(Mounting): 컴포넌트가 처음으로 DOM에 삽입될 때.
- 업데이트(Updating): 컴포넌트의 상태 또는 속성(props)이 변경되어 다시 렌더링될 때.
- 언마운트(Unmounting): 컴포넌트가 DOM에서 제거될 때.
클래스 컴포넌트의 라이프사이클 메서드
클래스 컴포넌트는 React.Component
를 상속받아 정의되며, 리액트는 특정 시점에 호출되는 다양한 라이프사이클 메서드를 제공합니다. 주요 라이프사이클 메서드는 다음과 같습니다:
1. constructor
컴포넌트가 생성될 때 호출됩니다. 초기 상태를 설정하고, 이벤트 핸들러를 바인딩할 때 주로 사용됩니다.
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 };
}
}
2. componentDidMount
컴포넌트가 처음으로 렌더링된 후 호출됩니다. 여기서 API 호출, 타이머 설정, DOM 조작 등을 수행할 수 있습니다.
componentDidMount() {
console.log('Component mounted');
}
3. componentDidUpdate
컴포넌트가 업데이트된 후 호출됩니다. 이전 상태와 비교하여 상태 변경 후의 작업을 수행할 수 있습니다.
componentDidUpdate(prevProps, prevState) {
if (prevState.count !== this.state.count) {
console.log('Count updated');
}
}
4. componentWillUnmount
컴포넌트가 DOM에서 제거되기 전에 호출됩니다. 여기서 타이머를 정리하거나 구독을 해제하는 등의 작업을 수행할 수 있습니다.
componentWillUnmount() {
console.log('Component will unmount');
}
5. shouldComponentUpdate
컴포넌트가 업데이트될지 여부를 결정하는 메서드로, 성능 최적화를 위해 사용됩니다. 기본적으로 true
를 반환하지만, 특정 조건에서 false
를 반환하여 렌더링을 방지할 수 있습니다.
shouldComponentUpdate(nextProps, nextState) {
return nextState.count !== this.state.count;
}
함수형 컴포넌트와 Hooks
함수형 컴포넌트는 클래스를 사용하지 않고 함수를 통해 컴포넌트를 정의합니다. 리액트 16.8에서 도입된 Hooks는 함수형 컴포넌트에서도 상태와 라이프사이클 기능을 사용할 수 있게 해줍니다. 주요 Hooks는 다음과 같습니다:
1. useState
상태 변수를 선언하고 관리하는 데 사용됩니다. 함수형 컴포넌트에서 상태를 다룰 수 있게 해줍니다.
const [count, setCount] = useState(0);
2. useEffect
사이드 이펙트를 관리하는 데 사용됩니다. componentDidMount
, componentDidUpdate
, componentWillUnmount
를 대체할 수 있으며, 종속성 배열을 통해 실행 시점을 제어할 수 있습니다.
useEffect(() => {
console.log('Component mounted or updated');
return () => {
console.log('Component will unmount');
};
}, [count]); // count가 변경될 때마다 실행
3. useContext
Context API를 통해 전역 상태를 관리하고, 함수형 컴포넌트에서 컨텍스트 값을 사용할 수 있게 해줍니다.
const theme = useContext(ThemeContext);
4. useReducer
복잡한 상태 로직을 관리할 때 사용됩니다. 리덕스와 유사한 방식으로 상태와 액션을 처리할 수 있습니다.
const [state, dispatch] = useReducer(reducer, initialState);
클래스 컴포넌트와 함수형 컴포넌트(Hooks)의 비교
1. 코드 구조
- 클래스 컴포넌트: 상태와 라이프사이클 메서드가 클래스 내에 정의되며, 상태와 관련된 로직이 분산되어 있을 수 있습니다.
- 함수형 컴포넌트(Hooks): 함수 내에서 모든 상태와 라이프사이클 로직이 관리되며, 코드가 간결하고 이해하기 쉬워집니다.
2. 리소스 관리
- 클래스 컴포넌트: 라이프사이클 메서드 간에 리소스 관리가 분산되어 있을 수 있습니다.
- 함수형 컴포넌트(Hooks):
useEffect
를 사용하여 마운트, 업데이트, 언마운트 단계를 하나의 훅에서 처리할 수 있어, 리소스 관리가 일관되고 간단합니다.
3. 가독성 및 유지보수성
- 클래스 컴포넌트: 메서드가 분리되어 있어 가독성이 떨어질 수 있으며, 상태 관리 로직이 여러 메서드에 걸쳐 분산될 수 있습니다.
- 함수형 컴포넌트(Hooks): 상태 관리와 사이드 이펙트 로직이 한 곳에 집중되어 있어 가독성과 유지보수성이 높습니다.
4. 성능 최적화
- 클래스 컴포넌트:
shouldComponentUpdate
를 사용하여 성능 최적화를 직접 구현할 수 있습니다. - 함수형 컴포넌트(Hooks):
React.memo
와useCallback
,useMemo
와 같은 훅을 사용하여 성능 최적화를 간단히 구현할 수 있습니다.
5. 테스트 용이성
- 클래스 컴포넌트: 상태와 메서드가 클래스에 묶여 있어 테스트가 복잡할 수 있습니다.
- 함수형 컴포넌트(Hooks): 함수형 패러다임 덕분에 단위 테스트가 상대적으로 더 쉽습니다.
결론
리액트의 클래스 컴포넌트와 함수형 컴포넌트(Hooks)는 각각의 장단점을 가지고 있으며, 특정 상황에 따라 적합한 방식을 선택할 수 있습니다. 클래스 컴포넌트는 복잡한 라이프사이클 관리와 기존 코드베이스에 적합하지만, 함수형 컴포넌트와 Hooks는 코드의 간결성, 유지보수성, 가독성을 크게 향상시킵니다. 최신 리액트 프로젝트에서는 함수형 컴포넌트와 Hooks를 주로 사용하여 더 효율적이고 이해하기 쉬운 코드를 작성하는 것이 권장됩니다.
- 공유 링크 만들기
- X
- 이메일
- 기타 앱