[React] React.js 강좌 13. 상태 관리 완전 정복 – Redux, Recoil, Zustand 비교와 활용법
1. 왜 상태 관리가 필요한가?
리액트에서 작은 컴포넌트를 만들 때는 useState 하나면 충분합니다.
하지만 앱이 커지면 여러 컴포넌트가 같은 데이터를 공유해야 하는 상황이 생깁니다.
예를 들어,
- 로그인 정보
- 다크모드 여부
- 장바구니 목록
- 사용자 프로필
이런 값들은 페이지 곳곳에서 사용되므로,
단순히 props로 전달하기에는 너무 복잡해집니다.
이럴 때 전역 상태 관리(Global State Management) 도구가 필요합니다.
2. 상태 관리의 발전 과정
리액트의 상태 관리는 크게 3단계로 발전해왔습니다.
단계 사용 방식 예시
| 1단계 | useState, useContext | 간단한 앱 |
| 2단계 | Redux | 복잡한 앱, 예측 가능한 상태 |
| 3단계 | Recoil, Zustand 등 | 간결하고 효율적인 대안 |
각 도구는 사용하는 목적과 철학이 다릅니다.
이제 각각을 차근히 살펴보겠습니다.
3. Redux – 가장 전통적인 상태 관리
Redux는 리액트 생태계에서 가장 오래된 전역 상태 관리 도구입니다.
핵심 개념은 “단일 스토어(Single Store)”입니다.
모든 전역 상태를 하나의 스토어에 저장하고,
액션(action)을 통해서만 상태를 변경할 수 있습니다.
구조 요약
- Store : 상태를 저장하는 공간
- Action : 상태를 변경하겠다는 ‘요청’
- Reducer : 상태 변경 로직을 정의하는 함수
// store.js
import { createStore } from 'redux';
const initialState = { count: 0 };
function counterReducer(state = initialState, action) {
switch (action.type) {
case 'INCREMENT':
return { count: state.count + 1 };
case 'DECREMENT':
return { count: state.count - 1 };
default:
return state;
}
}
export const store = createStore(counterReducer);
// Counter.js
import { useSelector, useDispatch } from 'react-redux';
function Counter() {
const count = useSelector((state) => state.count);
const dispatch = useDispatch();
return (
<div>
<p>현재 카운트: {count}</p>
<button onClick={() => dispatch({ type: 'INCREMENT' })}>+</button>
<button onClick={() => dispatch({ type: 'DECREMENT' })}>-</button>
</div>
);
}
Redux의 장점은 명확한 데이터 흐름과 예측 가능성입니다.
하지만 구조가 복잡하고, 코드가 길어지는 단점이 있습니다.
4. Recoil – React 팀이 인정한 차세대 상태 관리
Recoil은 Facebook(현 Meta)에서 만든 상태 관리 라이브러리로,
리액트의 상태 관리 철학과 가장 자연스럽게 어울리는 구조를 가지고 있습니다.
Redux가 중앙 스토어 하나를 사용하는 반면,
Recoil은 atom 단위의 독립적인 상태 조각을 사용합니다.
기본 예시
npm install recoil
// atoms.js
import { atom } from 'recoil';
export const countState = atom({
key: 'countState',
default: 0,
});
// Counter.js
import { useRecoilState } from 'recoil';
import { countState } from './atoms';
function Counter() {
const [count, setCount] = useRecoilState(countState);
return (
<div>
<p>Recoil 카운트: {count}</p>
<button onClick={() => setCount(count + 1)}>+</button>
</div>
);
}
Recoil은 각 atom이 독립적으로 관리되므로,
불필요한 리렌더링이 줄어듭니다.
또한, **비동기 상태 관리(Selector)**도 기본적으로 지원하여
서버 데이터 연동이 편리합니다.
5. Zustand – 가장 가벼운 상태 관리
Zustand는 독일어로 “상태(state)”라는 뜻입니다.
Redux보다 훨씬 단순하고,
코드 몇 줄로 전역 상태를 구성할 수 있습니다.
기본 예시
npm install zustand
// store.js
import { create } from 'zustand';
export const useStore = create((set) => ({
count: 0,
increase: () => set((state) => ({ count: state.count + 1 })),
decrease: () => set((state) => ({ count: state.count - 1 })),
}));
// Counter.js
import { useStore } from './store';
function Counter() {
const { count, increase, decrease } = useStore();
return (
<div>
<p>Zustand 카운트: {count}</p>
<button onClick={increase}>+</button>
<button onClick={decrease}>-</button>
</div>
);
}
Zustand는 훅 기반으로 동작하며,
보일러플레이트가 거의 없는 깔끔한 코드가 장점입니다.
또한 persist, subscribeWithSelector 등 플러그인 확장도 제공해
상태를 로컬스토리지에 저장하거나, 변경을 감지할 수도 있습니다.
6. 세 가지 도구 비교
항목 Redux Recoil Zustand
| 구조 | 단일 Store + Reducer | atom 단위 관리 | Hook 기반 Store |
| 코드량 | 많음 | 중간 | 매우 적음 |
| 비동기 지원 | Middleware 필요 (Thunk, Saga 등) | 내장 지원 (Selector) | 자체 구현 또는 외부 도구 |
| 러닝커브 | 높음 | 낮음 | 매우 낮음 |
| 성능 | 안정적 | 우수 | 매우 빠름 |
| 사용 예시 | 대규모 서비스 | 중형 규모 앱 | 개인 프로젝트, 경량 서비스 |
7. 어떤 걸 써야 할까?
- Redux → 대기업형, 대규모 프로젝트
(명확한 상태 추적, 로깅, DevTools 디버깅 필요할 때) - Recoil → 컴포넌트 단위의 자연스러운 상태 관리
(React의 철학에 가장 맞는 구조) - Zustand → 빠르고 간단하게 전역 상태를 다루고 싶을 때
(작은 프로젝트나 프로토타입에 적합)
🔹 요약하자면,
“Redux는 무겁지만 강력하고,
Recoil은 리액트 친화적이며,
Zustand는 가볍고 실용적이다.”
8. 실제 서비스 적용 팁
- 상태를 분류하라
- 전역 상태 : 로그인 정보, 사용자 설정 등
- 지역 상태 : 특정 페이지나 컴포넌트 내의 상태
- 서버 데이터는 별도 관리
- 전역 상태 도구로 서버 응답을 직접 관리하지 말고,
React Query, SWR과 함께 사용하라.
- 전역 상태 도구로 서버 응답을 직접 관리하지 말고,
- 개발 규모에 맞게 선택
- 3~4명 팀이라면 Recoil이나 Zustand로도 충분하다.
- 복잡한 권한 관리나 트랜잭션 로직이 있다면 Redux가 안전하다.
9. 마무리
이번 강의에서는 리액트 상태 관리의 전반적인 흐름을 살펴봤습니다.
각 라이브러리의 철학과 구조를 이해했다면,
이제 “우리 프로젝트에 맞는 선택”을 할 수 있을 것입니다.
핵심 정리:
- 상태 관리의 목적은 데이터 일관성과 유지보수성 확보
- Redux는 무겁지만 체계적, Recoil은 자연스럽고 유연, Zustand는 가볍고 빠름
- React Query와 함께 사용하면 서버/클라이언트 상태 분리가 깔끔해짐
다음 강의에서는 실제로 React Query를 활용해 서버 데이터와 전역 상태를 통합 관리하는 방법을 알아보겠습니다.