alpaka206

Zustand의 철학과 구조 - Redux와의 차이

date
Jul 6, 2025
slug
zustand-architecture-vs-redux
author
status
Public
tags
React
펑타이그레이터차이나
summary
Redux는 예측 가능한 상태 관리 도구지만, 복잡한 설정과 보일러플레이트로 인해 사용이 부담스러운 경우가 많습니다. Zustand는 Redux의 핵심 철학인 Flux 패턴은 유지하면서, 훨씬 더 간결하고 유연한 방식으로 상태를 관리할 수 있게 해줍니다. 이 글에서는 Zustand의 설계 철학, 중앙 집중형 구조, Slice Pattern, 그리고 Redux와의 구조적 차이점을 실제 코드 예제와 함께 설명합니다.
type
Post
thumbnail
category
💻 Frontend
updatedAt
Jan 4, 2026 08:58 AM
React에서 상태 관리를 고민하다 보면 Redux는 거의 한 번쯤은 고려하거나 경험해보게 됩니다. Flux 패턴 기반의 단방향 데이터 흐름, 예측 가능한 상태 관리, 미들웨어 확장성 등 많은 장점에도 불구하고, Redux는 다음과 같은 단점으로 자주 외면받기도 합니다.
  • 보일러플레이트 코드가 너무 많다. (액션, 리듀서, 타입 정의 등)
  • 상태를 변경하기 위해 거치는 과정이 복잡하다.
  • 단순한 동작도 코드 구조가 무겁다.
저도 Redux의 복잡성에 피로감을 느끼고 Recoil과 Zustand로 옮겨가게 되었습니다. 이 글에서는 Zustand의 설계 철학, 상태 구조, 그리고 실제 구성 방식이 Redux와 어떻게 다른지 정리해보고자 합니다.

1. Zustand는 왜 Flux 패턴을 유지했는가?

Zustand는 Redux와 마찬가지로 Flux 철학을 따르되, Flux의 엄격한 구조 대신 더 실용적인 API와 설계를 제공합니다.

Flux 패턴의 기본 흐름:

[컴포넌트] → [액션] → [리듀서 / 스토어] → [새 상태] → [컴포넌트 리렌더]
Zustand는 이 구조 중 액션 / 리듀서를 추상화하고, 단일 함수 기반의 create를 통해 “상태 + 액션”을 한 곳에 선언할 수 있도록 설계되었습니다.

2. Zustand의 상태 구조

Zustand는 create 함수를 통해 하나의 store에서 상태와 로직을 함께 정의합니다.
import { create } from 'zustand' const useStore = create((set) => ({ count: 0, increase: () => set((state) => ({ count: state.count + 1 })), }))
  • set 함수는 Zustand 내부 상태 변경 함수
  • increase는 상태 변경을 위한 간단한 액션
  • Redux처럼 액션 타입, 리듀서 분리 없이 상태와 로직을 한눈에 파악 가능

React 외부에서도 상태 접근 가능

Zustand는 React 훅 내부에 상태가 종속되지 않기 때문에, 어떤 위치에서든 상태 접근이 가능합니다.
const user = useStore.getState().user
이것은 서비스 로직, API 유틸, even listener 등에서 상태를 직접 읽거나 갱신해야 할 때 강력한 장점이 됩니다.

3. Redux와 Zustand의 구조적 비교

항목
Redux
Zustand
액션 정의
필수
불필요
리듀서
필수
없음
상태 타입 명시
필수
선택적
비동기 처리
thunk / saga 필요
그냥 async/await
미들웨어
별도 setup 필요
간단히 확장 가능 (devtools, persist 등)
초기 설정
복잡함
매우 간단

Zustand는 Redux의 '좋은 점만 남긴 대안'이라고 볼 수 있습니다.


4. 상태가 많아지면? → Slice Pattern 도입

Zustand에서 상태가 많아지면 하나의 파일에 모든 상태를 넣는 것이 부담스럽기 때문에, Slice Pattern을 도입해 상태를 기능별로 분할할 수 있습니다.
// slices/bearSlice.ts export const createBearSlice = (set) => ({ bears: 0, addBear: () => set((state) => ({ bears: state.bears + 1 })), })
export const createFishSlice = (set) => ({ fishes: 0, addFish: () => set((state) => ({ fishes: state.fishes + 1 })), })
import { create } from 'zustand' import { createBearSlice } from './slices/bearSlice' import { createFishSlice } from './slices/fishSlice' export const useStore = create((...a) => ({ ...createBearSlice(...a), ...createFishSlice(...a), }))게 하면 기능 단위의 상태 모듈화가 가능하며, 대규모 프로젝트에서도 유지보수가 쉬워집니다.

5. 실제로 사용해보면서 특히 좋았던 점들

  • 코드 작성 속도가 빨랐습니다.
    • 불필요한 액션/리듀서/타입 정의가 없으므로 작성 시간이 줄고, 디버깅도 단순해졌습니다.
  • 상태 추적이 쉬워졌습니다.
    • 모든 상태와 변경 로직이 같은 파일에 있어, IDE에서 바로 파악 가능합니다.
  • 다양한 상황에서의 유연성
    • 컴포넌트 외부에서도 상태 접근 가능
    • 서버에서 초기화 후 hydrate, 또는 SSR 환경에서도 유용

6. 결론

Zustand는 Redux의 복잡한 설정과 구조를 제거하고, Flux 철학은 유지한 채 실용적으로 다듬은 상태 관리 도구입니다.
상태를 선언하고 바로 사용할 수 있는 간결함, 외부 접근 가능성, slice를 통한 구조화까지 갖추고 있어 개인 프로젝트는 물론 팀 프로젝트에서도 충분히 사용할 수 있는 도구인 것 같습니다.