2025. 8. 22. 19:36ㆍ프로젝트
0. 목차
- 초창기 React: 함수형 vs 클래스형
- 컴포넌트의 한계
- Hook의 등장
1. 초창기 React: 함수형 vs 클래스형
React가 처음 나왔을 때, 컴포넌트에는 두 가지 방식이 있었습니다.
함수형(Function) 컴포넌트
function Hello(props) {
return <h1>Hello, {props.name}</h1>;
}
자바스크립트에서 함수가 호출되면, 그 실행 과정은 실행 컨텍스트(Execution Context) 라는 단위로 **스택(Stack)**에 쌓입니다. 실행이 끝나면 해당 컨텍스트는 스택에서 제거되고, 내부의 지역 변수와 매개변수도 함께 사라집니다.
즉, 함수형 컴포넌트가 렌더링될 때마다:
- 새로운 실행 컨텍스트가 스택에 생성되고,
- 함수 내부에서 선언된 변수들은 그 안에 저장되지만,
- 렌더링이 끝나면 실행 컨텍스트가 스택에서 제거되며 변수도 함께 소멸됩니다.
이 때문에 함수형 컴포넌트는 렌더링 사이에 상태값을 붙잡아 둘 수 없었고, 특정 시점(마운트, 업데이트, 언마운트)에 개입할 수 있는 방법도 존재하지 않았습니다.
클래스형(Class) 컴포넌트
import React from "react";
class Counter extends React.Component {
constructor(props) {
super(props);
// 힙에 존재하는 인스턴스의 상태
this.state = { count: 0 };
}
componentDidMount() {
// 마운트 직후 (DOM 준비 후) 1회 실행: 예) 데이터 fetch, 구독 시작
console.log("mounted");
}
componentDidUpdate(prevProps, prevState) {
// 업데이트 직후 실행: 예) props 변화 대응
if (prevState.count !== this.state.count) {
console.log("count changed:", this.state.count);
}
}
componentWillUnmount() {
// 언마운트 직전 정리(clean-up)
console.log("unmounted");
}
handleInc = () => this.setState(s => ({ count: s.count + 1 }));
render() {
return (
<button onClick={this.handleInc}>
Count: {this.state.count}
</button>
);
}
}
반대로 클래스형 컴포넌트(Class Component)는 React가 new 키워드로 인스턴스를 생성하여 힙(Heap) 메모리에 보관합니다.
- 이 인스턴스는 컴포넌트가 언마운트될 때까지 메모리에 남아 있으며,
- this.state와 라이프사이클 메서드(componentDidMount, componentDidUpdate, componentWillUnmount)는 그 인스턴스 내부에 저장되어 렌더링 사이에도 계속 유지됩니다.
즉, 클래스형 컴포넌트는 한 번 생성된 객체가 메모리에 살아남아 있기 때문에 상태 관리와 생명주기 제어가 가능했던 것입니다.
2. Class 컴포넌트의 한계
하지만 클래스 방식은 점점 문제가 드러났습니다.
- 복잡한 라이프사이클 로직
- 데이터 fetch → 구독(subscribe) → 정리(clean-up) 같은 로직이 componentDidMount, componentDidUpdate, componentWillUnmount로 흩어져 관리됐습니다.
- 한 기능에 관련된 코드가 여러 메서드에 나뉘다 보니 유지보수가 어려웠습니다.
- 로직 재사용의 불편함
- 여러 컴포넌트에서 동일한 상태 로직을 쓰려면 HOC(Higher-Order Component)나 Render Props 같은 패턴을 사용해야 했습니다.
- 이 방식은 코드가 중첩되고 가독성이 떨어졌습니다.
- this 바인딩 문제
- 클래스 내부 메서드에서 this를 올바르게 쓰기 위해 constructor에서 바인딩하거나, 화살표 함수를 쓰는 등의 번거로움이 있었습니다.
- 러닝 커브
- 함수형은 단순한데, 클래스 문법은 초심자에게 어렵게 느껴졌습니다.
- 특히 자바스크립트의 this 동작 원리를 알아야 했습니다.
3. Hook의 등장
React 팀은 “클래스 없이도 상태와 라이프사이클을 다룰 수 있게 만들자”라는 목표로 Hook을 도입했습니다. (React v16.8, 2019년)
- useState: 함수형 컴포넌트에서도 상태를 가질 수 있게 함
- useEffect: 라이프사이클을 하나의 API로 단순화 (mount/update/unmount 모두 처리)
- useContext, useReducer, useMemo, useCallback: 다양한 상태/성능 최적화 도구 제공
Hook의 핵심 원리는 React가 함수 호출 외부(Heap)에 상태 저장소를 두고, 호출 순서를 기반으로 상태를 이어주는 것입니다.
덕분에 함수형 컴포넌트도 “상태를 가진 UI 단위”로 진화할 수 있었습니다.
4. 마무리
이번 글에서는 React Hook의 등장배경과 전반적인 개요를 다뤘습니다.
각 Hook의 자세한 내용 및 사용법은 앞으로 개별 포스팅에서 더 깊이 살펴보겠습니다.
'프로젝트' 카테고리의 다른 글
| DOM(Document Object Model)과 Virtual DOM (3) | 2025.08.25 |
|---|---|
| NPM(Node Pacakge Manager) (5) | 2025.08.15 |
| SPA(Single Page Application) , Client-Side Routing (1) | 2024.06.12 |
| JWT(Json Web Token) 이해하기 (0) | 2024.05.16 |
| [GradeCalculator] TextField 컴포넌트의 error 속성 활용하기 (React js, Material UI) (0) | 2023.11.21 |