React에서 **상태(State)**는 시간이 지남에 따라 변할 수 있는 데이터를 의미하며, 이 데이터가 변경될 때마다 컴포넌트가 재렌더링되어 화면이 업데이트됩니다.
**상태관리(State Management)**는 애플리케이션의 **모든 상태(데이터)**를 체계적이고 예측 가능하며 효율적인 방식으로 다루는 일련의 과정 및 기술입니다.
쉽게 말해, 복잡한 애플리케이션의 모든 데이터를 **'중앙 통제실'**에 모아놓고, 누구든 필요한 시점에, 예측 가능한 규칙에 따라 데이터를 가져가거나 변경할 수 있도록 하는 시스템입니다.
🧐 상태관리가 필요한 이유: Props Drilling 문제
React의 기본 데이터 흐름은 **단방향(부모 → 자식)**입니다. 자식 컴포넌트에 데이터가 필요하면, 부모는 props를 통해 데이터를 전달해 줍니다.
문제는 애플리케이션의 규모가 커질 때 발생합니다.
1. Props Drilling (프롭스 드릴링)
애플리케이션이 복잡해지면, 멀리 떨어진 컴포넌트(예: 가장 상위의 App 컴포넌트가 가장 하위의 UserInfo 컴포넌트)에 데이터를 전달해야 할 때가 생깁니다.
이때, 중간에 있는 수많은 컴포넌트들은 자신에게는 필요 없는 데이터를 오직 '하위 컴포넌트에 전달해주기 위해서' props로 받아야 합니다. 이 과정이 마치 데이터를 여러 층의 컴포넌트를 드릴(drill)로 뚫고 전달하는 것 같다고 하여 Props Drilling이라고 부릅니다.
- 문제점: 코드를 이해하기 어려워지고, 중간 컴포넌트가 수정될 때마다 불필요하게 리렌더링이 발생하여 성능이 저하됩니다.
2. 상태 공유의 어려움
데이터가 부모-자식 관계가 아닌, 서로 형제 관계이거나 완전히 독립적인 두 컴포넌트(예: 장바구니 아이콘과 상품 목록) 간에 공유되어야 할 때, 데이터를 가장 가까운 공통 부모까지 끌어올려야(Lifting State Up) 합니다. 이 과정이 복잡해지면 상태의 출처를 파악하기 힘들어집니다.
🚀 상태관리 라이브러리의 등장과 중요성
상태관리 라이브러리(Recoil, Redux, Zustand 등)는 위의 Props Drilling과 복잡한 상태 공유 문제를 해결하기 위해 등장했습니다.
라이브러리의 핵심 역할
상태관리 라이브러리는 애플리케이션 내부에 **'전역 저장소(Global Store)'**를 만듭니다.
- 중앙 집중식 관리: 모든 중요한 상태(로그인 정보, 테마, 장바구니 등)를 이 중앙 저장소에 모아둡니다.
- 직접 접근: 어떤 컴포넌트든 계층 구조를 무시하고 저장소에 직접 접근하여 상태를 읽거나 변경할 수 있습니다.
- 반응성: 특정 컴포넌트가 저장소의 특정 상태를 구독하면, 그 상태가 변경될 때 해당 컴포넌트만 정확히 리렌더링됩니다. 중간 컴포넌트들은 불필요한 리렌더링을 겪지 않습니다.
상태관리가 중요한 이유
| 중요성 | 설명 |
| 예측 가능성 | 모든 상태 변화가 정해진 규칙(액션/디스패치 등)을 통해 이루어지므로, 데이터가 왜 바뀌었는지 쉽게 추적 가능합니다. |
| 유지보수성 향상 | 상태 로직이 컴포넌트에서 분리되어 저장소에 모여있기 때문에, 대규모 프로젝트의 코드 유지보수가 훨씬 쉬워집니다. |
| 개발 생산성 | 복잡한 props 전달 경로를 설계할 필요가 없어지고, 컴포넌트 설계에만 집중할 수 있어 개발 속도가 빨라집니다. |
따라서 상태관리 라이브러리는 복잡한 데이터 흐름을 체계화하고, 성능을 최적화하며, 대규모 애플리케이션의 유지보수성을 확보하기 위한 핵심적인 기술이므로 현대 React 개발에서 그 중요성이 매우 높습니다.
🧠 1. 상태(State)란?
리액트에서 상태(state) 는 “시간이 지나면서 바뀔 수 있는 데이터”를 의미합니다.
즉, UI에 영향을 주는 동적인 데이터예요.
예를 들어,
const [count, setCount] = useState(0);
count: 현재 상태 값
setCount: 상태를 변경하는 함수
0: 초기값
사용자가 버튼을 클릭하면 count 값이 변하고, 리액트는 자동으로 화면(UI)을 다시 렌더링해서 새로운 값을 반영합니다.
📌 즉, 리액트의 UI = 상태(state)의 함수
UI = f(state)
상태가 바뀌면 UI도 자동으로 바뀌는 구조예요.
🧩 2. 상태관리가 왜 필요한가?
리액트 앱이 커질수록 상태가 여러 컴포넌트 사이에서 복잡하게 얽히기 때문입니다.
예를 들어:
- 로그인 여부 (isLoggedIn)
- 장바구니 정보 (cartItems)
- API에서 받아온 데이터 (posts)
- UI 토글 상태 (isModalOpen)
이런 데이터들을 여러 컴포넌트가 공유하거나 수정해야 한다면, 어디서 바뀌었는지 추적하기가 매우 어려워집니다.
그래서 생기는 문제들 👇
| 문제 | 설명 |
| 데이터 일관성 깨짐 | 한 컴포넌트에서 수정했는데, 다른 곳에는 반영되지 않음 |
| 상태 흐름 복잡 | 부모 → 자식 → 손자… props로 전달하는 과정이 복잡 (“prop drilling”) |
| 유지보수 어려움 | 어디서 어떤 상태를 변경했는지 찾기 힘듦 |
이런 문제를 통제하고 일관된 상태 흐름을 유지하기 위해 상태관리가 필요합니다.
⚙️ 3. 상태관리의 핵심 목표
| 목표 | 설명 |
| 예측 가능성 (Predictability) | 상태가 언제, 왜, 어떻게 변하는지 명확해야 함 |
| 일관성 (Consistency) | 여러 컴포넌트가 같은 상태를 동일하게 바라봐야 함 |
| 유지보수성 (Maintainability) | 상태의 흐름을 쉽게 추적하고 수정 가능해야 함 |
| 성능 최적화 (Performance) | 불필요한 리렌더링을 방지해야 함 |
🧩 4. 상태관리 방식의 진화
(1) 컴포넌트 내부 상태 (useState, useReducer)
- 가장 기본적인 방식
- 상태를 한 컴포넌트 안에서만 사용할 때 적합
- 하지만 상태가 여러 곳에서 필요하면 props로 전달해야 함 → prop drilling 문제 발생
(2) 상위 컴포넌트에서 전달 (Props Lifting)
- 상태를 상위 컴포넌트로 끌어올리고 자식에게 전달
- 어느 정도 공유 가능하지만, 규모 커지면 구조가 복잡해짐
(3) Context API
- 전역 상태처럼 하위 컴포넌트 전체에 값 전달 가능
- 하지만 컴포넌트가 많아지면 리렌더링 성능 저하가 생김
- → 그래서 **리액트 공식 문서도 “가벼운 전역 상태만 Context로 관리하라”**고 권장
🧱 5. 그래서 나온 것들 — 상태관리 라이브러리들
대규모 프로젝트나 복잡한 상태 관리가 필요한 상황에서 등장한 게 바로
👉 전문 상태관리 라이브러리입니다.
| 라이브러리 | 특징 |
| Redux | 가장 오래되고 대표적인 전역 상태관리 도구. “단일 스토어 + 액션 + 리듀서” 구조로 예측 가능성 높음. |
| MobX | 반응형 상태관리. 관찰자 패턴 기반으로 직관적이고 코드 양이 적음. |
| Recoil | Facebook이 만든, React에 자연스럽게 통합되는 상태관리 라이브러리. atom 단위로 상태를 관리하고 React hook처럼 사용. |
| Zustand | 경량 상태관리. Redux보다 코드 간결하고 직관적. |
| Jotai, Valtio 등 | 함수형 리액트 코드 스타일에 맞는 모던한 경량 상태관리들. |
🌐 6. 상태관리 라이브러리가 중요한 이유
리액트 앱이 커질수록 “상태”는 단순 데이터가 아니라 앱의 중심 로직이 됩니다.
즉, 상태 관리 구조를 어떻게 설계하느냐가 프로젝트 퀄리티를 결정해요.
✅ 리액트의 진짜 핵심은 ‘상태 관리’에 있다
UI는 그 결과물일 뿐입니다.
📚 7. 비유로 이해하기
🏠 상태(state) = 집안의 모든 정보 (전등 ON/OFF, 문 열림, 냉장고 온도 등)
🧍♂️ 리액트 컴포넌트 = 집안의 각 방
🧭 상태관리 = 각 방이 같은 정보를 보고 조작하게 만드는 “중앙 제어 시스템”
- 작은 집이면 각 방이 직접 스위치 켜면 됨 (useState)
- 큰 빌딩이 되면, 중앙 제어 시스템(Redux, Recoil)이 필요함
🧾 요약 정리
| 구분 | 개념 | 특징 | 사용 상황 |
| useState | 컴포넌트 내부 상태 | 가장 기본적인 방법 | 단일 컴포넌트 내 데이터 |
| Context API | 전역 공유 가능 | 리렌더링 부하 있음 | 소규모 전역 데이터 |
| Redux | 중앙집중형, 액션 기반 | 예측 가능성 높음 | 대규모 상태 흐름 |
| MobX | 반응형, 간단한 코드 | 자동 추적, 마법처럼 동작 | 빠른 개발 필요시 |
| Recoil | React Hook 기반 | React스럽고 간결 | 최신 React 프로젝트 |
| Zustand | 경량, 심플한 API | 코드 짧고 직관적 | 중소형 프로젝트 |
'IT개발 > JS 관련' 카테고리의 다른 글
| JSON.stringify() vs JSON.parse() 완벽 이해하기 (입문자 친절 가이드) (0) | 2025.09.15 |
|---|---|
| [Vue] 초보자를 위한 Vue Router 완벽 가이드 (0) | 2025.04.21 |
| [JSP] 📚 JSP 핵심 태그 완벽 정리 | JSTL 기본 사용법과 예제 모음 (0) | 2025.04.08 |
| [GSAP] GSAP(GreenSock Animation Platform) 라이브러리(애니메이션 구현) (0) | 2025.02.26 |
| [JavaScript] JavaScript 구조 분해 할당(Destructuring Assignment) (0) | 2025.02.25 |
댓글