Zustand 讓 React 狀態變得太簡單

王大冶發表於2024-11-19
  • CSS技巧與案例詳解
  • vue2與vue3技巧合集
  • VueUse原始碼解讀

image.png

為什麼選擇 Zustand?

Zustand 是一個為 React 打造的現代化狀態管理庫,它以其簡潔的 API 和強大的功能正在改變前端開發的方式。相比 Redux 繁瑣的樣板程式碼(action types、dispatch、Provider等),Zustand 提供了更加優雅且直觀的解決方案。

核心特性

1. 基於 Hook 的簡潔API

import { create } from 'zustand'

// 建立 store
const useStore = create((set) => ({
  count: 0,
  increment: () => set((state) => ({ count: state.count + 1 })),
}))

// 在元件中使用
function Counter() {
  const count = useStore((state) => state.count)
  const increment = useStore((state) => state.increment)
  return <button onClick={increment}>{count}</button>
}

2. 靈活的狀態訂閱

Zustand 允許元件只訂閱它們需要的狀態片段,從而最佳化效能:

// 只訂閱特定欄位
const userName = useStore(state => state.user.name)
const userAge = useStore(state => state.user.age)

3. 去中心化的狀態管理

不同於 Redux 的單一狀態樹理念,Zustand 支援建立多個獨立的 store,更符合元件化開發的思想:

const useUserStore = create((set) => ({
  user: null,
  setUser: (user) => set({ user })
}))

const useCartStore = create((set) => ({
  items: [],
  addItem: (item) => set((state) => ({
    items: [...state.items, item]
  }))
}))

4. 派生狀態與淺比較

透過 useShallow() 可以輕鬆建立派生狀態:

import { useShallow } from 'zustand/shallow'

// 當任意原始狀態變化時更新
const { name, age } = useStore(
  useShallow(state => ({ 
    name: state.user.name, 
    age: state.user.age 
  }))
)

5. 非同步操作支援

內建支援非同步 action,無需額外的中介軟體:

const useStore = create((set, get) => ({
  users: [],
  fetchUsers: async () => {
    const response = await fetch('/api/users')
    const users = await response.json()
    set({ users })
  }
}))

6. 狀態更新控制

支援細粒度的狀態更新控制:

// 部分更新(預設行為)
set({ user: { ...get().user, name: 'John' } })

// 完全替換
set({ user: { name: 'John' } }, true)

7. 直接訪問狀態

除了 hooks,還支援直接訂閱狀態變化:

const store = create(...)
const unsubscribe = store.subscribe(state => {
  console.log('State changed:', state)
})

實戰示例

下面是一個購物車功能的完整示例:

const useCartStore = create((set, get) => ({
  items: [],
  total: 0,
  
  addItem: (item) => set((state) => {
    const newItems = [...state.items, item]
    return {
      items: newItems,
      total: newItems.reduce((sum, item) => sum + item.price, 0)
    }
  }),
  
  removeItem: (id) => set((state) => {
    const newItems = state.items.filter(item => item.id !== id)
    return {
      items: newItems,
      total: newItems.reduce((sum, item) => sum + item.price, 0)
    }
  }),
  
  clearCart: () => set({ items: [], total: 0 })
}))

總結

Zustand 憑藉其簡潔的 API、靈活的狀態管理方式以及出色的效能,正在成為 React 應用狀態管理的首選方案。它既保留了 Redux 的核心優勢(不可變性、狀態與UI解耦等),又極大地簡化了開發流程。如果正在尋找一個現代化的狀態管理方案,Zustand 絕對值得一試。

注:這篇文章在保持原文核心內容的基礎上,加入了更多程式碼示例和實際應用場景,使內容更加充實和實用。透過分類組織和詳細的示例說明,使讀者能更好地理解和應用 Zustand。

首發於公眾號 大遷世界,歡迎關注。📝 每週一篇實用的前端文章 🛠️ 分享值得關注的開發工具 ❓ 有疑問?我來回答

本文 GitHub https://github.com/qq449245884/xiaozhi 已收錄,有一線大廠面試完整考點、資料以及我的系列文章。

相關文章