TechFeedTechFeed
라이브러리난이도 보통⏱ 슬라이스 단위(점진적)

Redux에서 Zustand로 마이그레이션

Redux→Zustand
요약: Zustand는 보일러플레이트 없이 훅으로 상태를 읽고 쓰는 경량 스토어입니다. Redux의 action/reducer/dispatch 구조를 단일 store 함수로 대폭 줄일 수 있습니다.

왜 옮기나

  • Redux는 action·reducer·dispatch·provider 등 보일러플레이트가 많습니다.
  • Zustand는 약 1KB로 Provider 없이 훅만으로 전역 상태를 다룹니다.
  • 비동기 로직을 store 안에서 그냥 async 함수로 작성할 수 있습니다.

전제 — 현재 상태

Redux(또는 Redux Toolkit) + react-redux, store/slice/action, useSelector/useDispatch.

마이그레이션 단계

1
Zustand 설치

Zustand를 설치합니다. Provider 래핑이 필요 없습니다.

npm install zustand
2
slice를 store로

reducer+action을 create()의 단일 store로 옮깁니다. set으로 상태를 갱신합니다.

import { create } from 'zustand'
const useStore = create((set) => ({
  count: 0,
  inc: () => set((s) => ({ count: s.count + 1 })),
}))
3
컴포넌트에서 훅 사용

useSelector/useDispatch 대신 store 훅에서 필요한 값·액션을 선택합니다.

const count = useStore((s) => s.count)
const inc = useStore((s) => s.inc)
4
Provider 제거

react-redux의 <Provider store>를 제거합니다. Zustand는 모듈 스토어라 래핑이 불필요합니다.

⚠️ 막히는 케이스 · 함정

  • 여러 값을 한 번에 선택할 때 객체를 반환하면 매 렌더 새 참조가 되어 리렌더가 늘 수 있습니다 — 개별 선택 또는 useShallow를 쓰세요.
  • Redux DevTools가 필요하면 devtools 미들웨어를 명시적으로 추가합니다.
  • 서버 상태(API 캐시)는 Zustand보다 TanStack Query가 더 적합할 수 있습니다 — 전역 UI 상태와 서버 상태를 구분하세요.
✅ 검증: 전역 상태 읽기/쓰기·비동기 액션이 동일하게 동작하는지, 불필요한 리렌더가 늘지 않았는지 React DevTools로 확인합니다.
ZustandRedux상태관리Reactstore

관련 마이그레이션

관련 가이드

async await, 클라이언트 컴포넌트, use | 로그인 버튼에서 유저를 기다렸는데 빨간 줄이면?useSearchParams, Suspense, 정적 빌드 | 로컬은 되는데 빌드만 멈추면?Objects are not valid as a React child, 객체, Promise | 카카오 유저를 화면에 넣었는데 빨간 줄이면?window is not defined, document, 브라우저 API | use client를 붙였는데도 빌드가 죽으면?