Zustand是什麼?React前端狀態管理

更新於 發佈於 閱讀時間約 12 分鐘
Zustand是什麼?React前端狀態管理
未來文章一併更新於此網站 Hogan.B Lab
並且包含多語系 繁體中文英文日文簡體中文
Zustand 吉祥物

關於狀態管理

在介紹Zustand之前,要來講講「狀態管理」是什麼?
現行網頁越來越複雜,也有了前端與後端的分別,其中前端比較偏向畫面呈現、UI \ UX、使用者流程、不同裝置有無跑版...等等。後端比較偏功能上的實作,包含資料庫管理、登入、註冊...等等。
那麼針對前端越來越複雜,也開始有了框架的概念,而現行流行的三大框架,分別為React、Vue、Angular。不同框架也會有不同的「狀態管理」方式,例如:
React :基本上只需要管理資料,並且由「狀態」來去渲染
Vue:有資料與元件的「雙向綁定」
而基於React這個框架而言,又可以大致上可以分為
Local State
  • useState
  • useReducer
Context
  • useContext
Third Party
  • Redux
  • Mobx
  • Zustand
看到這邊應該可以理解,光是一個React框架中的「狀態管理」就已經相當複雜了。
因此這篇只會針對Zustand來進行講解,也會用實例來進行介紹。
我們也可以透過以下的套件下載總量對比來知道,過去一年中Redux、Mobx、Zustand盛行程度。
https://npmtrends.com/mobx-vs-react-redux-vs-zustand

Zustand 是什麼?

根據Zustand官方說法,這是一個輕量、快速,基於Flux以及Hook概念出現的「狀態管理」套件。
p.s. 上面那隻熊是Zustand標誌性的吉祥物!
其中Zustand 也是為了解決一些複雜的React狀態管理問題,例如:Zombie Child Problem、React Concurrency、Context Loss。
如果想要更了解這些問題是什麼的話,可以參考以下連結
Zombie Child Problem:React Redux 文件
React Concurrency:React 官方文件
React Context Loss:Stack Overflow
我們也可以透過Zustand官方知道他們想要擊敗Redux的野心

Zustand用法

下面兩個簡單的用法,是針對JavaScript的使用者。

建立第一個Store

Zustand是基於Hook建立的,因此第一個建立的就是由Custom Hook建立的Store裡面可以放入包含變數、物件、函數。並且可以透過Set、Get來去做資料的「狀態管理」
import create from 'zustand'
const useBearStore = create((set) => ({
  bears: 0,
  increasePopulation: () => set((state) => ({ bears: state.bears + 1 })),
  removeAllBears: () => set({ bears: 0 }),
}))

針對元件進行綁定

因為是使用Hook,因此在任何元件中皆可以直接載入做使用。也可以針對這些狀態進行渲染,可以看到短短的幾行就可以處理完成,算是Zustand中的一大福音。
function BearCounter() {
  const bears = useBearStore((state) => state.bears)
  return <h1>{bears} around here ...</h1>
}
function Controls() {
  const increasePopulation = useBearStore((state) => state.increasePopulation)
  return <button onClick={increasePopulation}>one up</button>
}
這邊也針對TypeScript使用者提供簡單的Zustand範例

Zustand TypeScript 寫法

在Zustand 我們會使用create來去建立新的store。透過函數傳入,透過Hook來回傳狀態,並且進行再次渲染。
import create from "zustand"
type Product = { sku: string; name: string; image: string }
type CartState = {
  products: Product[]
  cart: { [sku: string]: number }
  addToCart: (sku: string) => void
  removeFromCart: (sku: string) => void
}
// Selectors
// ...
// Initialize our store with initial values and actions to mutate the state
export const useCart = create<CartState>(set => ({
products: [
// ...
],
cart: {},
// Actions
// ...
}))
這邊也另外展示Redux以及Mobx的寫法,讀者也可以比較其差異,不過這篇不會針對Redux或是Mobx進行講解,只會針對Zustand以及其狀態管理進行講解

Redux TypeScript 寫法

import { createSlice, configureStore, PayloadAction } from "@reduxjs/toolkit"
import { TypedUseSelectorHook, useDispatch, useSelector } from "react-redux"
// Slices
// Definee the shape of the state and how to mutate it
type ICart = { [sku: string]: number }
const cartInitialState: ICart = {}
const cartSlice = createSlice({
  name: "cart",
  initialState: cartInitialState,
  reducers: {
  // ...
  },
})
type IProduct = { sku: string; name: string; image: string }
const productsInitialState: IProduct[] = [
  // ...
]
const productsSlice = createSlice({
  name: "products",
  initialState: productsInitialState,
  reducers: {},
})
// Actions
// ...
// Selectors
// ...
// Store
export const store = configureStore({
  reducer: {
  cart: cartSlice.reducer,
  products: productsSlice.reducer,
  },
})
// ...
const App = () => {
return (
  <Provider store={store}>
  <NavigationContainer>
  <Stack.Navigator>{/* ... */}</Stack.Navigator>
  <StatusBar style="auto" />
  </NavigationContainer>
  </Provider>
  )
}

Mobx TypeScript寫法

import { types, Instance } from "mobx-state-tree"
const Product = types.model({
  sku: types.string,
  name: types.string,
  image: types.string,
})
// Model and type our data with mobx state tree
const CartStore = types
  .model("CartStore", {
    products: types.array(Product),
    cart: types.map(types.number),
  })
  // Actions to mutate the state
  .actions(store => ({
    // ...
  }))
  // Views are like selectors
  .views(self => ({
    // ...
  }))
type CartStoreType = Instance<typeof CartStore>
// Spin up a hook to use our store and provide initial values to it
let _cartStore: CartStoreType
export const useCart = () => {
  if (!_cartStore) {
    _cartStore = CartStore.create({
      products: [
        // ...
      ],
      cart: {},
    })
  }
  return _cartStore
}

Zustand是否能超越Context以及Redux呢?

https://github.com/pmndrs/zustand#why-zustand-over-redux
根據Zustand官方,列舉以上幾點,這邊也簡單講解一下

Redux

Redux本身是一個較為複雜的狀態管理工具,會有Actioins、View、State的流程
以下是Redux的官方資料流示意圖,也可以知道如果要從無到有使用Redux的狀態管理工具學習門檻是比較高的。
https://dev.to/oahehc/redux-data-flow-and-react-component-life-cycle-11n

Context

Context 本身雖然是歸類在狀態管理,但實際上比較像是一個集中式觸發狀態的方式。
https://dev-yakuza.posstree.com/en/react/context-api/
比起Zustand而言是會發散在各個檔案,不好進行管理

結論

Zustand本身是一個滿容易學習的狀態管理工具,且自己在工作產品使用上也是相對方便的,包含針對狀態進行Set、Get或是在元件中進行使用都是相對方便,滿推薦給想針對React進行狀態管理的讀者。
感謝觀看~對於以上內容如有任何疑問或是想要討論的地方,都歡迎留言或是私訊我!
為什麼會看到廣告
希望能透過「React框架白話文運動」系列文章,利用口語化語表以及簡單的程式碼範例,能讓讀者更明白React的各種應用。 系列文章會講述以下: 1. 了解 ES6 JavaScript 語法 2. 了解 React 的運作原理 3. 了解 React 的狀態管理 4. 使用 React Hook管理狀態並且存取資料
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
為何大公司都使用Nx ? Monorepo的工具五分鐘快速建置 簡介:Nx 一個快速、有效、有相當好延展性的Monorepo工具 理念:Nx 與知名程式編輯器Visual Studio Code有著相同的設計哲學,以Nx核心來說,擁有著簡潔、不模糊、明瞭的特性。
大型是一個有點模糊的詞彙,什麼是大型呢? 是100人以上的前端大型開發專案? 還是超過一千個頁面的大型專案?或是跨國部門的前端大型開發專案呢? 為了解決上述的問題,Monorepo前端大型架構就這樣誕生了。
為何大公司都使用Nx ? Monorepo的工具五分鐘快速建置 簡介:Nx 一個快速、有效、有相當好延展性的Monorepo工具 理念:Nx 與知名程式編輯器Visual Studio Code有著相同的設計哲學,以Nx核心來說,擁有著簡潔、不模糊、明瞭的特性。
大型是一個有點模糊的詞彙,什麼是大型呢? 是100人以上的前端大型開發專案? 還是超過一千個頁面的大型專案?或是跨國部門的前端大型開發專案呢? 為了解決上述的問題,Monorepo前端大型架構就這樣誕生了。
你可能也想看
Google News 追蹤
Thumbnail
現代社會跟以前不同了,人人都有一支手機,只要打開就可以獲得各種資訊。過去想要辦卡或是開戶就要跑一趟銀行,然而如今科技快速發展之下,金融App無聲無息地進到你生活中。但同樣的,每一家銀行都有自己的App時,我們又該如何選擇呢?(本文係由國泰世華銀行邀約) 今天我會用不同角度帶大家看這款國泰世華CUB
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
先從react開始: 其實市面上有許多前端框架像是react,angular,vue... 至於為什麼我會選擇react…
Thumbnail
本文介紹了在網站開發中如何運用狀態機的原則和設計方法。通過具體案例分析,以及狀態和數據的區分,詳細介紹了狀態機的設計原則和應用。讀者可以通過本文瞭解如何將狀態機應用於實際的網站開發中。
React Hooks 是 React 16.8 中引入的一組新的 API,允許你在函數組件中使用狀態和其他 React 特性,而不需要寫類組件。 狀態管理: useState 鉤子允許在函數組件中添加狀態。 副作用管理: useEffect 鉤子允許處理副作用,如數據獲取、訂閱和手動 DO
Thumbnail
在程式任何地方都能修改各種react組件狀態的做法分享
Thumbnail
在 Vue 中,組件是構建應用程式的基本單位,而 props 是組件間傳遞資料的主要方式之一,本文將介紹 Vue 中的 props,並通過實際範例展示如何使用 props 實現組件間的資料傳遞。
Thumbnail
在 Vue 3 的 Composition API 中,引入了兩個重要的響應式數據處理工具:ref 和 reactive,本文將介紹ref 和 reactive,並透過實際範例來解釋它們的用法和差異。
Thumbnail
前言 現在的前端需求已經越來越高,要考慮HTML及CSS的切版美觀程度,以及React以及Flutter所提出的元件(Componet、widget)觀念,也就是將元件模組化,使元件可以更動態的被程式運行,而不用靜態的客製化每一個介面。開發一個好的元件可以提升整體的開發速度,讓任何使用元件的開發者
Thumbnail
前端開發者常會遇到需要網頁素材的情況,雖然在公司中都可能有可以配合的平面設計師或是UIUX設計師,但在這個多工高效的時代不免也需要前端開發者也可以處理簡單的設計,也可提升設計審美或與設計師溝通的能力。 然而前端開發者也算是擁有設計師的天賦,透過程式碼來完成平面設計,將網頁的每個介面都視為平面設計,
Thumbnail
env 環境變數的設定,通常是為為了 server 而設定的,能快速的切換狀態,但現在的網頁開始,前端的範圍逐漸往後端靠近,所以在設定,也會有 client 的變數會想要在 .env 的情況。此篇就是以 nuxt 為實作,分享此內容 前端架構 最常見的 front 架構,就是把專案 buil
Thumbnail
現代社會跟以前不同了,人人都有一支手機,只要打開就可以獲得各種資訊。過去想要辦卡或是開戶就要跑一趟銀行,然而如今科技快速發展之下,金融App無聲無息地進到你生活中。但同樣的,每一家銀行都有自己的App時,我們又該如何選擇呢?(本文係由國泰世華銀行邀約) 今天我會用不同角度帶大家看這款國泰世華CUB
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
先從react開始: 其實市面上有許多前端框架像是react,angular,vue... 至於為什麼我會選擇react…
Thumbnail
本文介紹了在網站開發中如何運用狀態機的原則和設計方法。通過具體案例分析,以及狀態和數據的區分,詳細介紹了狀態機的設計原則和應用。讀者可以通過本文瞭解如何將狀態機應用於實際的網站開發中。
React Hooks 是 React 16.8 中引入的一組新的 API,允許你在函數組件中使用狀態和其他 React 特性,而不需要寫類組件。 狀態管理: useState 鉤子允許在函數組件中添加狀態。 副作用管理: useEffect 鉤子允許處理副作用,如數據獲取、訂閱和手動 DO
Thumbnail
在程式任何地方都能修改各種react組件狀態的做法分享
Thumbnail
在 Vue 中,組件是構建應用程式的基本單位,而 props 是組件間傳遞資料的主要方式之一,本文將介紹 Vue 中的 props,並通過實際範例展示如何使用 props 實現組件間的資料傳遞。
Thumbnail
在 Vue 3 的 Composition API 中,引入了兩個重要的響應式數據處理工具:ref 和 reactive,本文將介紹ref 和 reactive,並透過實際範例來解釋它們的用法和差異。
Thumbnail
前言 現在的前端需求已經越來越高,要考慮HTML及CSS的切版美觀程度,以及React以及Flutter所提出的元件(Componet、widget)觀念,也就是將元件模組化,使元件可以更動態的被程式運行,而不用靜態的客製化每一個介面。開發一個好的元件可以提升整體的開發速度,讓任何使用元件的開發者
Thumbnail
前端開發者常會遇到需要網頁素材的情況,雖然在公司中都可能有可以配合的平面設計師或是UIUX設計師,但在這個多工高效的時代不免也需要前端開發者也可以處理簡單的設計,也可提升設計審美或與設計師溝通的能力。 然而前端開發者也算是擁有設計師的天賦,透過程式碼來完成平面設計,將網頁的每個介面都視為平面設計,
Thumbnail
env 環境變數的設定,通常是為為了 server 而設定的,能快速的切換狀態,但現在的網頁開始,前端的範圍逐漸往後端靠近,所以在設定,也會有 client 的變數會想要在 .env 的情況。此篇就是以 nuxt 為實作,分享此內容 前端架構 最常見的 front 架構,就是把專案 buil