일상이 개발

React 상태 관리 제대로 설계하기 – Context, Zustand, Redux 완전 비교와 전략적 선택 가이드

아빠고미 2025. 5. 4. 12:06
반응형

React 상태 관리 제대로 설계하기 – Context vs Zustand vs Redux 전략 비교와 선택 기준

React 앱을 만들다 보면 상태 관리 도구를 고를 때 항상 고민이 생깁니다.

  • 🧩 Context로 충분할까?
  • ⚡ 상태 변화가 많다면 Redux가 나을까?
  • ☁️ 요즘은 Zustand를 많이 쓴다는데 왜일까?

이번 글에서는 React에서 대표적인 상태 관리 도구인 Context API, Redux, Zustand를 아키텍처 관점에서 비교하고, 언제, 무엇을, 왜 선택해야 하는지 실무적인 기준을 중심으로 정리해보겠습니다.

 

React 상태 관리 제대로 설계하기 – Context, Zustand, Redux 완전 비교와 전략적 선택 가이드

 


1. ⚙️ 상태 관리란 무엇인가?

컴포넌트는 상태에 따라 렌더링이 달라집니다. 즉, 상태는 UI를 움직이는 동력입니다.

상태의 종류는 다음과 같이 나눌 수 있어요:

  • Local State: 개별 컴포넌트에서만 사용하는 상태 (useState)
  • Global State: 여러 컴포넌트가 공유하는 상태 (ex. 사용자 정보)
  • Server State: API 요청으로 불러오는 외부 데이터 상태 (React Query 등)
  • URL State: 주소창 쿼리스트링으로 반영되는 상태 (useSearchParams)

👉 이 글에서는 특히 Global State 관리 도구를 중심으로 비교합니다.


2. 🧱 Context API – 기본 제공, 하지만 한계가 뚜렷

✅ 장점

  • React 자체 내장 – 별도 설치 불필요
  • 가벼운 앱에서 충분히 활용 가능
  • 의존성이 없어 작고 단순한 프로젝트에 적합

❌ 단점

  • 상태가 많아지면 재렌더링 폭발
  • Provider 중첩이 심해짐 ("Provider hell")
  • 비동기 처리, 미들웨어, DevTools 없음

📦 코드 예시

// ThemeContext.js
const ThemeContext = createContext();

export const ThemeProvider = ({ children }) => {
  const [mode, setMode] = useState('light');
  return (
    <ThemeContext.Provider value={{ mode, setMode }}>
      {children}
    </ThemeContext.Provider>
  );
};

export const useTheme = () => useContext(ThemeContext);

🔍 언제 사용하면 좋을까?

  • 앱 전체에서 공유되는 작고 단순한 상태 (예: 다크모드)
  • 비즈니스 로직보단 UI 상태용

3. ⚡ Zustand – 심플하고 강력한 전역 상태 관리 도구

Zustand는 독일어로 ‘상태(state)’를 의미합니다. React 팀에서 만든 것도 아니고, Redux 팀에서 만든 것도 아니지만, 최근 많은 프로젝트에서 선택되고 있는 가볍고 직관적인 상태 관리 도구입니다.

✅ 주요 특징

  • 별도 Provider 없이 useStore() 훅으로 접근
  • Context처럼 구조가 복잡하지 않음
  • Redux보다 훨씬 적은 코드로 비슷한 기능 가능
  • Devtools, Persist, Middleware 플러그인 제공

📦 기본 사용 예시

// useUserStore.js
import { create } from 'zustand';

export const useUserStore = create((set) => ({
  user: null,
  setUser: (user) => set({ user }),
  clearUser: () => set({ user: null }),
}));
// 컴포넌트에서 사용
const user = useUserStore((state) => state.user);
const setUser = useUserStore((state) => state.setUser);

🔁 상태 셀렉터 사용 시 리렌더링 최소화

  • 컴포넌트는 필요한 상태만 선택해서 구독
  • 불필요한 리렌더링 방지 가능
// 이렇게 쓰면 성능에도 좋고 가독성도 굿!
const { user, clearUser } = useUserStore((state) => ({
  user: state.user,
  clearUser: state.clearUser,
}));

4. ⚖️ Context vs Zustand 비교 요약

기준 Context API Zustand
설치 여부 필요 없음 설치 필요 (npm i zustand)
전역 상태 접근 useContext() useStore()
리렌더링 제어 제어 어려움 선택적 구독으로 가능
Provider 중첩 많아질 수 있음 없음
DevTools 없음 있음 (플러그인)
비동기 지원 직접 구현 필요 내장(set 함수 안에 async 가능)

👉 간단한 UI 상태라면 Context, 복잡한 전역 상태와 성능이 중요하다면 Zustand가 유리합니다.

5. 🏗️ Redux – 복잡한 상태 관리의 정석, 하지만 무겁다?

Redux는 한때 거의 모든 React 앱에서 채택되던 전역 상태 관리 도구입니다. 하지만 코드 양이 많고, 설정이 복잡해진다는 이유로 최근에는 대체 도구로 이동하는 흐름도 있죠.

✅ 주요 특징

  • 전통적인 Flux 패턴 기반의 엄격한 상태 흐름
  • 전역 상태의 흐름이 명확
  • 미들웨어를 통한 사이드이펙트 처리
  • DevTools, 로깅, 타임트래블 디버깅까지 제공

📦 예시 구조 (Redux Toolkit 기준)

// store.js
import { configureStore } from '@reduxjs/toolkit';
import userReducer from './userSlice';

export const store = configureStore({
  reducer: {
    user: userReducer,
  },
});
// userSlice.js
import { createSlice } from '@reduxjs/toolkit';

const userSlice = createSlice({
  name: 'user',
  initialState: { user: null },
  reducers: {
    setUser: (state, action) => {
      state.user = action.payload;
    },
    clearUser: (state) => {
      state.user = null;
    },
  },
});

export const { setUser, clearUser } = userSlice.actions;
export default userSlice.reducer;

🧠 미들웨어 사용 예 (Redux Thunk)

// userThunk.js
export const fetchUser = () => async (dispatch) => {
  try {
    const response = await fetch('/api/user');
    const data = await response.json();
    dispatch(setUser(data));
  } catch (err) {
    console.error(err);
  }
};

6. 📊 Zustand vs Redux vs Context – 최종 비교 요약

항목 Context Zustand Redux
사용 난이도 쉬움 쉬움 어려움
리렌더링 성능 낮음 높음 높음
DevTools 없음 있음 최고 수준
미들웨어 지원 직접 구현 기본 제공 (middleware) thunk, saga 등 확장
학습 곡선 낮음 낮음 높음
앱 규모 적합성 소규모 중~대규모 대규모/복잡한 상태

7. 🧠 마무리 – 어떤 상태 관리 도구를 선택할 것인가?

✅ 사용 추천 기준

  • 작고 단순한 앱: Context API로 충분
  • 중규모 앱: Zustand 권장 – 가볍고 유연
  • 대규모 기업용 앱: Redux + 미들웨어 (Toolkit 필수)

💬 조합 팁

  • UI 토글, 테마 등은 Context로
  • 사용자 정보, 전역 필터, 장바구니 등은 Zustand로
  • 복잡한 로직 처리, 데이터 플로우는 Redux로

상태 관리 도구는 “정답”이 아니라 “적합성”의 문제입니다. 이번 글이 여러분의 프로젝트에 가장 적합한 선택을 하는 데 도움이 되었길 바랍니다!


유익하셨다면 댓글, 공감, 공유로 응원 부탁드립니다 🙌

반응형