什麼是 Zustand?
Zustand 是一款基於 Flux 架構的輕量級 React 狀態管理 工具,以其極簡的 API、無需 Provider 包裹以及優異的效能而聞名。它使用 Hooks 作為主要互動方式,解決了傳統 Redux 樣板程式碼(Boilerplate)過多的問題,同時支援非同步操作、中間件(Middleware)與 DevTools,是現代前端開發中替代 Redux 的熱門首選方案。
在現代前端開發中,選擇合適的 React 狀態管理 方案至關重要。當我選擇 Zustand 作為狀態集中管理的解決方案時,有很多原因促使我做出這個決定。Zustand 的輕量級和彈性特性使其在架構上無縫穿梭於專案的各個角落,避免了因架構限制而導致的可讀性下降和優化難度增加。
以下是我使用 Zustand 快兩年後的一些心得,透過這份 Zustand 教學,我將從幾個層面來深入分析其優勢。
為什麼不該再繼續用 Redux 了?
選擇狀態集中管理的解決方案時,Zustand 的輕量級和彈性特性讓我不再依賴 Redux。儘管 Redux 曾經為 FLUX 單向資料流提供接近典範的解決方案,但隨著時間推移,它逐漸暴露出以下問題:
Redux 的局限性
- 樣板程式碼繁多:Redux 需要大量的樣板程式碼,包括 actions、reducers 和 store 的設置,這增加了開發的複雜性。
- 過度抽象:對於剛進入前端領域的開發者來說,Redux 的抽象層可能使簡單的狀態管理變得複雜,這對於小型或中型應用來說顯得多餘。而且,理解 Redux 的工作原理(如中間件和非同步處理)需要時間,可能影響團隊的開發效率。
- 效能問題: 在狀態更新過程中,Redux 可能導致不必要的重新渲染,這在大型應用中會成為性能瓶頸。
隨著 React 的演進,如 Hooks 的加入,Redux 的生態系統顯得越來越過時,儘管 Redux Toolkit 嘗試解決這些問題,但歷史的包袱仍然存在。因此,我開始探索更好的選擇。
Zustand 的特點與優勢
在使用 Zustand 快兩年後,我從以下幾個層面進行了分析:
簡單易用的文件
官方文件清晰可讀,並具有可愛的設計和滾動視差效果。這不僅提高了開發者的學習效率,也使得查找資訊變得更加直觀。此外,Zustand 的社群也提供了大量的範例和教程,進一步降低了入門的難度。
無需轉換 DevTool
從 Redux 轉移過來時,原有的 DevTool 可以直接使用,降低了學習成本。這意謂著開發者可以快速上手,無需重複學習工具的使用方法,從而提高開發效率。
快速入門
QuickStart 實現迅速,讓開發者能夠迅速上手,Zustand 使用 hooks 來管理狀態,這與 React 的設計理念更加契合,使得狀態的使用變得更直觀。
官網簡潔易懂: https://zustand-demo.pmnd.rs/
1 | import { create } from "zustand"; |
Zustand 設計模式: Slice Pattern
Zustand 提供的 Slice Pattern 使狀態管理更加模組化,便於組織和擴展。
這種設計模式讓開發者可以將狀態劃分為不同的「切片」,每個切片可以獨立管理,這樣不僅提高了可讀性,還促進了團隊的協作開發,因為不同的開發者可以同時在不同的切片上工作,降低了衝突的風險。
1 | const createFishSlice = (set) => ({ |
Zustand X 個人職涯發展
每次換新工作時,理論上都應該學會一次新的解決方案。
我記得最早使用 Zustand 時,因為專案時間緊迫,但我的老闆給了我很大的自由度,當時也是新專案而且時程有被報告追趕的壓力,於是投資了一隻看起來很可愛的熊當狀態管理的工具。
當然,我認為要選就要選可愛的?!
Zustand 對專案的優化
Zustand 的設計使其易於與其他函式庫(如 React Query)整合,並且提供 middleware,使需求的實現變得簡單。我建議維持 Single Source of Truth 的原則,以避免狀態不一致的問題。
Zustand 的進階寫法支援狀態持久化和多層的狀態更新,這些特性使開發變得更加方便。
接下來,熊熊稱霸世界?!
支援 Redux Devtool
1 | import { devtools } from 'zustand/middleware' |
支援狀態持久化到瀏覽器的儲存
1 | import { create } from "zustand"; |
支援非同步
Zustand 支援非同步操作,開發者可以在 store 裡面實作 fetch 及 setState() 的邏輯。
1 | const useFishStore = create((set) => ({ |
支援 immer 進行多層的物件操作
1 | import { create } from "zustand"; |
架構面: 提供在元件外操作共用的狀態
Zustand 允許開發者在元件外直接操作共用狀態,提高了靈活性。
底下是官網的範例可以透過已經持久化的 store 本身直接進行 getState() 或是 setState() 的狀態操作。
1 | const useDogStore = create(() => ({ paw: true, snout: true, fur: true })); |
因為這樣的特性,Zustand 也提供了 vanillajs 的版本,便於在多種使用場景下使用。
1 | import { createStore } from 'zustand/vanilla' |
FAQ:Zustand 狀態管理常見問題
Q1:Zustand 與 Redux 最大的區別是什麼?
A:Zustand 不需要 Provider 包裹整個應用,這意味著它不會在狀態更新時導致整棵元件樹的 Context 重新計算。此外,Zustand 的程式碼量通常只有 Redux 的 1/10。
Q2:什麼時候該選擇 Zustand 而不是 React Context?
A:當您的狀態更新頻率較高,或者狀態邏輯跨越大量元件時,Zustand 的訂閱機制(Subscription)能精確只重新渲染使用該狀態的元件,效能優於會導致全域重新渲染的 Context。
Q3:Zustand 適合大型專案嗎?
A:絕對適合。透過 Slice Pattern 與其對 TypeScript 的優異支援,Zustand 在管理複雜的大型應用狀態時比 Redux 更加清晰且易於擴展。
在新的狀態管理方案中,Zustand 以其簡潔性和靈活性,讓我在開發中感到滿意,在專案需要協助和交接的過程,大多數時候不太需要多餘的解釋,接手的人不論資淺資深都可以快速的上手,使得團隊協作更加順利,隨著開發技術的演進,選擇合適的狀態管理工具變得至關重要,而 Zustand 無疑是當前最佳的選擇之一。
喜歡這篇文章,請幫忙拍拍手喔 🤣
