C
React/Advanced State/Lesson 17

Zustand Global State Management

30 min·theory
TypeScript

Zustand Global State Management

💡 Why Should You Learn This?

🎯 It has 95% smaller bundle size than Redux while providing the same functionality.
💼 It manages global state intuitively without any boilerplate code.
It has excellent TypeScript support, offering outstanding type safety.
🔗 As of 2024, both startups and large enterprises are migrating to Zustand.
🏢 실무에서는
In production, user login information, theme settings, and shopping cart data are managed with Zustand. Unlike Redux, there is no need to write complex actions/reducers — you simply change state with plain functions, and any component can subscribe to only the state it needs.

Concepts

We will learn the practical selection criteria between Zustand and Recoil — the two dominant React state management libraries as of 2025. We cover every factor that matters in real projects: bundle size, learning curve, type safety, and more.

Why Does This Matter?

More teams are adopting Zustand over Redux in large-scale services, cutting bundle size by 30% and doubling developer productivity. Alongside Recoil, developed by Meta, Zustand is gaining attention as a next-generation state management solution, and questions about it have become essential in 2025 frontend interviews.

Core Concepts

Zustand means "state" in German. It is an extremely lightweight state management library — like a small drawer that stores only the state you need, simply and efficiently. Recoil, built by Facebook, is an atomic-based state manager: you compose complex state from small state units, much like snapping Lego bricks together.

Key Points

  • Zustand: 2.9KB vs Recoil: 79KB — Zustand wins decisively on bundle size
  • Zustand requires no boilerplate; Recoil uses atom/selector patterns for fine-grained control
  • As of 2025, Zustand is more stable; Recoil is still in an experimental stage
💻 Zustand Basic Implementation — 2025 Recommended Pattern
import { create } from 'zustand'
import { persist } from 'zustand/middleware'

// 2025 latest pattern: immer and persist combination
interface UserStore {
  user: User | null
  isLoading: boolean
  login: (credentials: LoginCredentials) => Promise<void>
  logout: () => void
}

export const useUserStore = create<UserStore>()(persist(
  (set, get) => ({
    user: null,
    isLoading: false,
    
    login: async (credentials) => {
      set({ isLoading: true })
      try {
        const user = await authAPI.login(credentials)
        set({ user, isLoading: false })
      } catch (error) {
        set({ isLoading: false })
        throw error
      }
    },
    
    logout: () => {
      set({ user: null })
      authAPI.logout()
    }
  }),
  {
    name: 'user-storage',
    partialize: (state) => ({ user: state.user }) // Persist only what's needed
  }
))
💻 Recoil Basic Implementation — Atomic Pattern
import { atom, selector, useRecoilState, useRecoilValue } from 'recoil'

// Atom definition
export const userAtom = atom<User | null>({
  key: 'userAtom',
  default: null,
})

export const isLoadingAtom = atom<boolean>({
  key: 'isLoadingAtom',
  default: false,
})

// Define derived state with Selector
export const userStatusSelector = selector({
  key: 'userStatusSelector',
  get: ({ get }) => {
    const user = get(userAtom)
    const isLoading = get(isLoadingAtom)
    
    if (isLoading) return 'loading'
    if (user) return 'authenticated'
    return 'guest'
  },
})

// Usage in component
function UserProfile() {
  const [user, setUser] = useRecoilState(userAtom)
  const userStatus = useRecoilValue(userStatusSelector)
  
  return (
    <div>
      <p>Status: {userStatus}</p>
      {user && <p>Welcome, {user.name}!</p>}
    </div>
  )
}

💡 ⚠️ Common Mistakes

  • Unnecessarily splitting state across multiple Zustand stores and recreating a props-drilling problem
  • Using duplicate atom keys in Recoil and causing unexpected state sharing
  • Introducing Recoil into a small-scale project without considering bundle size, resulting in over-engineering

💡 🎯 Interview Prep

Q: Which would you choose between Zustand and Recoil, and why?
Q: What are the advantages of Zustand over Redux?
Q: Explain the atom and selector pattern in Recoil

Hint: Base your choice on project scale and team context — use Zustand for small-to-medium projects or fast development cycles, and Recoil for large-scale apps with complex state dependencies. Mention bundle size, learning curve, type safety, and community support together, and include real-world experience examples.

⚛️ React Pattern — Zustand Global State Management

Learn step by step, with code, how to use Zustand Global State Management in React.
1 🧩 1. When to Use Zustand Global State Management
Situations where this feature is needed.
2 💻 2. Writing the Code
Basic usage of Zustand Global State Management.
3 🎨 3. Rendered Output
What the user sees on screen.
4 💡 4. Practical Tips
Common pitfalls and best practices.

🎮 Zustand Global State Management — Step-by-Step Understanding

Click each step to read through the content, then mark your progress with the ✓ Got it button.
🖥️ Result — rendered React component
✏️ React 코드 수정하기 (클릭해서 열기)
⚛️ React 18 + Babel Standalone — see the result first, then edit the code yourself.

Check Quiz

Which of the following is a correct advantage of Zustand?
💡 Zustand lets you write store creation, subscription, and updates with minimal code. There are no complex actions, reducers, or middleware like Redux — you simply start with `const useStore = create(set => ...)`.
Zustand — Top-tier Global State Today - React