前端核心知识

状态管理
三大方案 深度对比

Zustand · Redux · MobX —— 它们代表了三种截然不同的状态管理哲学。 本文将从架构思想、API 设计、性能表现、生态全景等多个维度,带你深入理解每一个方案的核心原理与最佳实践。

核心哲学

三种管理哲学,三条设计之路

Zustand

最小化主义

  • Store 即函数
  • 一行代码创建状态
  • 直接在组件中使用 hook
  • 去掉一切不必要的抽象

"少即是多,简单即是力量"

Redux

可预测性至上

  • Action 描述意图
  • Reducer 纯函数处理变更
  • 单一数据源
  • 时间旅行调试

"每一个状态变更都可追溯"

MobX

响应式透明化

  • Observable 自动追踪依赖
  • Mutation 与普通 JS 无异
  • Computed 自动缓存
  • Reactions 自动触发更新

"让状态管理回归直觉"

Zustand 深度解析

Zustand🐻 Bear Necessities for State

Zustand 是一个轻量、快速的状态管理库。它抛弃了 Redux 的繁琐模板代码,用最简洁的 API 实现了响应式状态管理。无需 Provider,无需 Context,只需一个 hook 即可。

诞生年份2019
包大小~1KB
样板代码极低
学习曲线

核心优势

  • +极小的包体积(~1KB gzipped)
  • +几乎零样板代码
  • +无需 Provider 包裹
  • +支持中间件(persist, devtools, immer)
  • +原生支持 React 18 concurrent features
  • +TypeScript 友好
  • +可以在 React 组件外使用

潜在不足

  • -生态不如 Redux 庞大
  • -大型应用的组织模式需要自行约定
  • -缺少官方的标准化 DevTools(但支持 Redux DevTools)
  • -社区文档相对较少

最佳适用场景

中小型应用快速开发
对性能有极高要求的场景
需要在组件外部访问状态
想要最小化依赖和模板代码的团队
代码示例

从代码看三种风格差异

Zustand — 简洁到极致

store/counter.ts — 创建 Store
import { create } from 'zustand'
import { persist } from 'zustand/middleware'

interface CounterState {
  count: number
  bears: number
  increase: () => void
  decrease: () => void
  reset: () => void
  addBears: (n: number) => void
}

// 一行代码,一个函数,就是整个 store
export const useCounterStore = create<CounterState>()(
  persist(
    (set) => ({
      count: 0,
      bears: 0,
      increase: () => set((s) => ({ count: s.count + 1 })),
      decrease: () => set((s) => ({ count: s.count - 1 })),
      reset: () => set({ count: 0 }),
      addBears: (n) => set((s) => ({ bears: s.bears + n })),
    }),
    { name: 'counter-storage' }
  )
)
components/Counter.tsx — 使用 Store
'use client'
import { useCounterStore } from '@/store/counter'

export function Counter() {
  // 选择性订阅,精准重渲染
  const count = useCounterStore((s) => s.count)
  const increase = useCounterStore((s) => s.increase)
  const decrease = useCounterStore((s) => s.decrease)

  return (
    <div className="counter">
      <button onClick={decrease}>-</button>
      <span>{count}</span>
      <button onClick={increase}>+</button>
    </div>
  )
}

// 💡 无需 Provider 包裹!
// 💡 可以在组件外直接调用:
//    useCounterStore.getState().increase()

🐻 Zustand 数据流

ComponentuseStore(selector)
Storecreate() → state + actions
setStateset() → 触发订阅

Redux Toolkit — 现代 Redux

store/counterSlice.ts — 创建 Slice
import { createSlice, PayloadAction } from '@reduxjs/toolkit'

interface CounterState {
  value: number
  status: 'idle' | 'loading'
}

const initialState: CounterState = {
  value: 0,
  status: 'idle',
}

export const counterSlice = createSlice({
  name: 'counter',
  initialState,
  reducers: {
    increment: (state) => {
      // Immer 让你"直接修改",实际生成新状态
      state.value += 1
    },
    decrement: (state) => {
      state.value -= 1
    },
    incrementByAmount: (state, action: PayloadAction<number>) => {
      state.value += action.payload
    },
    reset: () => initialState,
  },
})

export const { increment, decrement, 
               incrementByAmount, reset } 
  = counterSlice.actions
export default counterSlice.reducer
components/Counter.tsx — 使用 Selector
'use client'
import { useSelector, useDispatch } from 'react-redux'
import { increment, decrement } from '@/store/counterSlice'
import type { RootState } from '@/store/store'

export function Counter() {
  const count = useSelector(
    (state: RootState) => state.counter.value
  )
  const dispatch = useDispatch()

  return (
    <div className="counter">
      <button onClick={() => dispatch(decrement())}>
        -
      </button>
      <span>{count}</span>
      <button onClick={() => dispatch(increment())}>
        +
      </button>
    </div>
  )
}

// 📌 需要用 <Provider store={store}> 包裹
// 📌 Redux DevTools 自动集成

🔄 Redux 单向数据流

Viewdispatch(action)
Action{ type, payload }
Reducer纯函数 (state, action)
Store新 State → 订阅通知

MobX — 响应式魔法

store/CounterStore.ts — Observable Store
import { makeAutoObservable, runInAction } from 'mobx'

class CounterStore {
  count = 0
  name = 'My Counter'

  constructor() {
    // MobX 6: 自动将所有属性变为 observable
    makeAutoObservable(this)
  }

  get doubled() {
    // computed: 自动缓存,依赖变化时重算
    return this.count * 2
  }

  increment() {
    this.count += 1  // 直接修改!
  }

  decrement() {
    this.count -= 1
  }

  // 异步操作需要用 runInAction
  async fetchData() {
    const data = await api.getCount()
    runInAction(() => {
      this.count = data.count
    })
  }
}

export const counterStore = new CounterStore()
components/Counter.tsx — Observer 自动追踪
'use client'
import { observer } from 'mobx-react-lite'
import { counterStore } from '@/store/CounterStore'

// observer HOC 自动追踪组件用到的
// 所有 observable 属性,精准重渲染
export const Counter = observer(() => {
  const { count, doubled, increment, decrement } 
    = counterStore

  return (
    <div className="counter">
      <button onClick={decrement}>-</button>
      <span>{count} (×2 = {doubled})</span>
      <button onClick={increment}>+</button>
    </div>
  )
})

// 💡 无需 Provider!Store 是普通实例
// 💡 直接 import 即可在任何地方使用
// 💡 computed 自动缓存,不会重复计算

📊 MobX 响应式三角

Observable (State)被追踪的状态数据makeAutoObservable(this)
Computed (Derived)从 State 自动派生的值get 属性 / 自动缓存
Reaction (Effect)状态变化时自动执行observer() / autorun()

✨ 修改 Observable → Computed 自动重算 → Reaction (UI) 自动重渲染

全面对比

多维度对比矩阵

📦 包体积(越小越好)

Zustand
95%
Redux
60%
MobX
55%

📝 样板代码(越少越好)

Zustand
95%
Redux
50%
MobX
85%

📈 学习曲线(越高越易学)

Zustand
90%
Redux
45%
MobX
70%

🛠️ 生态/工具链

Zustand
60%
Redux
95%
MobX
70%

⚡ 运行时性能

Zustand
85%
Redux
75%
MobX
90%

🏗️ 大型项目适用性

Zustand
65%
Redux
95%
MobX
80%

🔧 DevTools 支持

Zustand
70%
Redux
95%
MobX
65%

🧩 TypeScript 体验

Zustand
95%
Redux
90%
MobX
75%
特性ZustandRedux (RTK)MobX
编程范式类 Flux(简化)Flux / 单向数据流响应式 / Observable
状态定义方式create() 函数createSlice() + ReducerClass + makeAutoObservable
状态更新set() 直接更新dispatch(action) → reducer直接赋值 (mutation)
不可变性可选(Immer 中间件)必须(Immer 内置)可变(Mutable)
Provider❌ 不需要✅ 需要❌ 不需要
异步处理在 actions 中直接 asynccreateAsyncThunk / RTK QueryrunInAction() 包裹
DevTools支持 Redux DevTools专属 DevTools(最强)mobx-extensions
持久化persist 中间件redux-persist手动序列化
代码分割✅ 动态创建 store⚠️ 需要配置✅ 动态实例化
SSR 支持✅ 原生支持✅ 需配置✅ 需配置
进阶模式

进阶模式与最佳实践

MobX 提供 flow 处理异步逻辑(基于 generator),mobx-state-tree (MST) 提供结构化的状态树模型。

MobX flow() 异步 & MST 模型
import { makeAutoObservable, flow } from 'mobx'

class UserStore {
  users = []
  state = 'idle'

  constructor() {
    makeAutoObservable(this)
  }

  // flow: 基于 generator 的优雅异步
  fetchUsers = flow(function* (this: UserStore) {
    this.state = 'loading'
    try {
      const response = yield fetch('/api/users')
      const data = yield response.json()
      this.users = data
      this.state = 'done'
    } catch (e) {
      this.state = 'error'
    }
  })
}

// ─── MobX State Tree (MST) ───
import { types } from 'mobx-state-tree'

const User = types.model('User', {
  id: types.identifier,
  name: types.string,
  email: types.string,
})

const RootStore = types
  .model('RootStore', {
    users: types.array(User),
    selectedId: types.maybeNull(types.string),
  })
  .views((self) => ({
    get selectedUser() {
      return self.users.find((u) => u.id === self.selectedId)
    },
  }))
  .actions((self) => ({
    selectUser(id: string) {
      self.selectedId = id
    },
    addUser(user: { id: string; name: string; email: string }) {
      self.users.push(user)
    },
  }))
TypeScript 体验

TypeScript 类型体验对比

ZustandS

泛型 create<T>() 天然类型推断,selector 自动推导返回类型

const useStore = create<MyState>()(
  (set) => ({
    count: 0,
    // set 的参数自动推断
    inc: () => set((s) => ({ count: s.count + 1 })),
  })
)
// useStore((s) => s.count) → number ✅
ReduxA

RTK 的 createSlice 自动推断 action 类型,但 RootState 手动定义

// RootState 需要从 store 推导
type RootState = ReturnType<typeof store.getState>
const useSelector = createSelectorHook<RootState>()
// useSelector(s => s.counter.value) → number ✅
// PayloadAction<T> 可约束 payload 类型
MobXB+

Class 属性自然有类型,但 observable 包装器的类型推断偶尔不理想

class Store {
  count: number = 0  // ✅ 自然类型
  name: string = ''
}
// class 属性天然有类型
// 但 makeAutoObservable 的推断
// 偶尔需要手动标注
选型指南

如何选择?一张决策图

你的项目规模如何?

🟢 小 / 中型项目

追求简洁 & 快速迭代?

🐻 Zustand
🟣 大型 / 企业级项目

需要严格可追溯 & 团队规范?

🔄 Redux (RTK)
🩷 复杂交互 & 实时 UI

数据关系复杂 & 仪表盘?

📊 MobX
最终总结

没有最好的,只有最合适的

🐻 Zustand

如果你追求极致简洁、零模板代码、快速上手 —— Zustand 是 2024 年的首选。它用最少的概念解决了 80% 的状态管理需求。

🔄 Redux

如果你的项目规模大、团队成员多、需要严格的状态变更审计 —— Redux Toolkit 依然是最稳的选择。它的工具链和生态系统无可匹敌。

📊 MobX

如果你偏好面向对象思维、数据模型关系复杂、需要极致的渲染性能 —— MobX 的响应式系统会让你的开发体验如丝般顺滑。

🎯 理解原理比记忆 API 更重要 —— 选一个最适合你团队和项目的,然后深入掌握它。