1. 상태 관리란 무엇인가?
React에서 상태(state)는 컴포넌트의 렌더링 결과를 결정하는 데이터입니다.
- 지역 상태(Local State): useState, useReducer 등을 통해 개별 컴포넌트 안에서 관리
- 전역 상태(Global State): 여러 컴포넌트가 공유해야 하는 상태 (예: 사용자 로그인 정보, 테마, 언어 설정 등)
- 서버 상태(Server State): 서버에서 가져온 데이터로, 동기화가 필요 (예: 게시글 목록, API 응답 데이터)
React의 상태 관리 도구들은 이 세 가지 범주를 효율적으로 다루는 데 초점을 맞추고 있습니다.
2. Context API – 전역 상태 관리의 기초
Context API는 React가 제공하는 기본 내장 기능으로, props drilling 문제를 해결하기 위해 등장했습니다.
즉, 여러 단계에 걸쳐 props를 전달하지 않고 전역적으로 데이터를 공급할 수 있습니다.
// ThemeContext.js
import { createContext } from "react";
export const ThemeContext = createContext("light");
// App.js
<ThemeContext.Provider value="dark">
<Toolbar />
</ThemeContext.Provider>
// Toolbar.js
const theme = useContext(ThemeContext);
✅ 장점
- React 내장 기능 → 별도 라이브러리 불필요
- 소규모 전역 상태 관리에 적합 (테마, 언어, 인증 여부 등)
❌ 단점
- 상태가 커질수록 리렌더링 비용 증가
- 복잡한 로직 관리에는 불편
👉 따라서 규모가 작은 앱이나 간단한 전역 데이터 공유에는 Context API만으로 충분합니다.
3. Redux – 복잡한 전역 상태 관리의 표준
Redux는 가장 오래되고 널리 사용되는 상태 관리 라이브러리입니다. 상태를 단일 스토어(Single Store) 에 보관하고, 액션(Action)과 리듀서(Reducer)를 통해 상태를 업데이트합니다.
// store.js
import { configureStore, createSlice } from "@reduxjs/toolkit";
const counterSlice = createSlice({
name: "counter",
initialState: { value: 0 },
reducers: {
increment: (state) => { state.value += 1 },
decrement: (state) => { state.value -= 1 }
}
});
export const { increment, decrement } = counterSlice.actions;
export const store = configureStore({ reducer: { counter: counterSlice.reducer } });
✅ 장점
- 예측 가능한 상태 업데이트 (순수 함수 기반)
- 강력한 Redux DevTools를 통한 디버깅 가능
- 대규모 애플리케이션에서 검증된 패턴
❌ 단점
- 보일러플레이트 코드가 많음 (→ Redux Toolkit으로 개선)
- 학습 곡선이 상대적으로 가파름
👉 Redux는 대규모 프로젝트에서 팀 단위 협업이 필요할 때, 혹은 상태 추적과 디버깅이 중요한 경우 유리합니다.
4. React Query – 서버 상태 관리의 혁신
React Query는 로컬 상태가 아닌 서버 상태 관리에 초점을 맞춘 라이브러리입니다.
API 요청과 캐싱, 동기화, 로딩/에러 상태 관리 등을 자동으로 처리해 주기 때문에 “프론트엔드의 데이터 페칭 표준”으로 불립니다.
import { useQuery } from "@tanstack/react-query";
function PostList() {
const { data, isLoading, error } = useQuery({
queryKey: ["posts"],
queryFn: () => fetch("/api/posts").then(res => res.json())
});
if (isLoading) return <p>Loading...</p>;
if (error) return <p>Error...</p>;
return (
<ul>
{data.map(post => <li key={post.id}>{post.title}</li>)}
</ul>
);
}
✅ 장점
- 캐싱 자동화 (같은 요청은 재사용)
- 리페치(refetch), 무효화(invalidate), 백그라운드 업데이트 지원
- API 기반 서비스에 최적화
❌ 단점
- 로컬 상태 관리에는 적합하지 않음
- 별도 라이브러리 의존
👉 React Query는 서버 데이터가 많은 서비스(예: 블로그, 쇼핑몰, 대시보드) 에 특히 효과적입니다.
5. 어떤 상황에서 무엇을 선택할까?
- 소규모 앱 / 간단한 전역 데이터 → Context API
- 대규모 앱 / 복잡한 상태 로직 → Redux (Redux Toolkit 필수)
- API 중심 서비스 / 서버 데이터 동기화 → React Query
실제로는 이들을 조합해서 사용하기도 합니다.
예를 들어,
- 전역 UI 상태(테마, 다크모드) → Context API
- 복잡한 비즈니스 로직(인증, 권한, 장바구니) → Redux
- 서버 데이터(API 응답, 게시글, 유저 목록) → React Query
이렇게 역할을 분리하면 프로젝트가 커져도 관리가 훨씬 수월해집니다.
6. 마무리
React는 useState 하나로 시작하지만, 애플리케이션 규모가 커질수록 다양한 상태 관리 전략이 필요해집니다.
- Context API는 작고 단순한 전역 상태
- Redux는 예측 가능한 대규모 전역 상태 관리
- React Query는 서버 데이터 관리의 혁신
세 가지를 상황에 맞게 적절히 조합하는 것이 현명한 접근입니다.
앞으로 React 18+, Next.js와의 결합, 그리고 서버 컴포넌트 시대까지 고려하면 상태 관리의 중요성은 더욱 커질 것입니다.
개발자는 단순히 “도구 선택”을 넘어서, 상태의 성격을 구분하고 최적의 관리 방법을 설계하는 능력이 필요합니다.
'프론트엔드' 카테고리의 다른 글
Tailwind CSS or ShadCN UI 가이드 (1) | 2025.08.26 |
---|---|
Next.js 프레임워크 SSR vs SSG 차이 완벽 정리 (2) | 2025.08.24 |
Next.js로 블로그 만들기 (2) | 2025.08.23 |
React 기본 Hook 성능까지 끌어올리는 사용법 (3) | 2025.08.22 |
React 입문 가이드 (1) | 2025.05.23 |