從 Jotai 到 Zustand
date
Apr 17, 2025
slug
from-jotai-to-zustand
status
Published
tags
JavaScript
React
Frontend
summary
本文探討 jotai 和 zustand 的優劣,以及最終為何選擇 zustand
type
Post
React 生態系中有許多狀態管理 library,其中 Jotai 及 Zustand 都是輕量且熱門的選擇,而這兩套也都是 dai-shi 所開發,但它們的設計理念和使用方式有所不同,本文將介紹兩者的異同以及為何最終我選擇 Zustand。
Jotai v.s. Zustand
Jotai 是 atom based 的狀態管理,而 Zustand 是大而全的狀態管理機制。後者推出後即主打能從 Redux 快速 migrate 過去,因此使用的人不少,稱得上是主流狀態管理工具。
而這兩套我在個人和公司的大小專案內都有使用過,說實話以狀態管理而言,兩者能達到的效果基本上一樣,以下給幾個範例:
狀態在 React 內存取
jotai 的用法相當簡潔,類似 react state 的語法。zustand 雖然在定義 store 上較為複雜,但可控度高,在狀態數量多的情境,也能更方便的 grouping。
狀態在 React 外存取
兩者都有提供
createStore
讓使用者可以操作 store 去 get/set 資料可以發現 jotai 需要使用 atom (config) 來和 store 互動,相較 zustand 比較不方便。
多層的 Provider 結構
Jotai 有自帶 Provider API,而 zustand 可以藉由 React Context 去達到多層 Provider 的效果。
依據 Jotai 先吃 context 後讀 default store 的實作,也可以封裝出同效果的 Provider mode zustand,這邊附上程式碼供大家參考 https://gist.github.com/maxam2017/2df7eb10e3f8ed9654cde6a21b5b4302
Render Optimization:避免改 A,B 也跟著改變
Jotai 在這題有很大的優勢,因為 atom 彼此獨立,所以不會有互相影響的問題。而 zustand 則類似 Redux,可以用 selector pattern 做到,而且 zustand 自帶 shallow equality check,所以大多時候可以直接 select 就好,如果需要客製化也有像 reselect, rereselect 的
createWithEqualityFn
API 可以使用。能否只拿 state setter
Jotai 會需要注意使用的 hook,無法都無腦使用 useAtom。而 zustand 和上題類似,利用 selector pattern 就有很好的最佳化。
Devtools
兩者都有提供 devtools,Jotai 類似 React Query 需要自己 mount 在畫面上,而 zustand 則是借助 Redux Devtools 來顯示。
從上述幾點來看,可以發現 Jotai 和 Zustand 在功能上是雷同的、可以互相取代,都是完整的狀態管理工具。但個人覺得就語法而言,Zustand 更為直覺,也能直接 create 出 hook 或是 store 來操作,光是 import 上,就比 jotai 要拿取很多 atom 簡潔不少。
語法的差異
以 jotai 而言,最單純的做法可能是不暴露出 atom,都利用 custom hook 來互動
但把 atom 的實作隱藏起來了,會少很多可能性 (e.g.
- 沒有暴露 atom,沒辦法和 store 互動
而 Provider mode 也近乎半殘,沒辦法做 store 的調整
但 atom 暴露出來,可能是悲劇的開始。因為 atom 是分散的,會 import 在各處外,也能做 derived atom 會讓之間的相依性變得複雜,一不小心多人開發容易寫出複雜難懂的程式碼,也可能寫出一些魔法 (可以參考 Jotai Universe Org 下的複雜 Jotai 的應用場景 😃)
結
雖然 Jotai 和 Zustand 功能上都能完成大多數狀態管理需求,但依照專案大小與團隊習慣,會有不同的適用情境。如果你想快速實作幾個 UI 狀態,Jotai 是個不錯的選擇;但當專案變大、狀態管理越來越複雜時,Zustand 在維護成本與彈性上的優勢會越來越明顯。因此目前 React 生態系中,我覺得 Zustand 是個相對適合的選擇。
後記
這篇其實是 jotai 畢業文。去年底接了公司的新專案後,選擇導入 jotai 來作為全域狀態管理,在以前的經驗都是用在少數一兩個狀態,所以覺得很單純。但新專案的規模不小、狀態複雜,彼此又有一定的關聯度,因此 jotai 用到最後除了每次 import 很多 atom 很阿雜外,邏輯又散落在四處,加上多人開發,三、四個月後過去,每次找狀態都相當痛苦。因此才開始思考什麼是好的狀態管理,除了能用外,也需要讓團隊能更好的使用才是合適的工具。
因此最近也找了一天空檔,把 jotai 全部轉換成 zustand,順便落下這篇心得。如果你也正在選擇狀態管理工具,希望這篇文章能給你一些方向。