成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Zustand 使用優(yōu)化:關(guān)于自動(dòng)生成選擇器

開(kāi)發(fā) 開(kāi)發(fā)工具
本文我們講解了在使用 Zustand 時(shí)的一個(gè)小優(yōu)化,關(guān)于自動(dòng)生成選擇器。借助 createSelectors(),我們可以更加輕松、快捷的訪問(wèn) Store 中的狀態(tài)或是 Action。

Zustand[1] 是目前 React 生態(tài)里比較受歡迎的一個(gè)狀態(tài)庫(kù),主要是因?yàn)橛梅ㄉ系暮?jiǎn)潔。

Zustand 簡(jiǎn)單使用

首先安裝 zustand:

# NPM
npm install zustand
# Or, use any package manager of your choice.

接著從 zustand 庫(kù)中引入 create API 就能創(chuàng)建同時(shí)包含狀態(tài)和用于修改狀態(tài)的方法的 Store 對(duì)象了。

import { create } from 'zustand'

const useBearStore = create((set) => ({
  bears: 0,
  increasePopulation: () => set((state) => ({ bears: state.bears + 1 })),
  removeAllBears: () => set({ bears: 0 }),
  updateBears: (newBears) => set({ bears: newBears }),
}))

這里,create() 接受一個(gè)回調(diào)函數(shù)用于定義初始 Store 中包含的內(nèi)容:

  • bears 是狀態(tài)
  • increasePopulation()、removeAllBears()、updateBears() 則是用于修改 bears 這個(gè)狀態(tài)的方法,又叫 Action

同時(shí),create() 返回的 useStore() 是一個(gè) React Hook。useBearStore() 接收的是一個(gè)用于從 Store 中提取內(nèi)容的回調(diào)函數(shù),又叫“選擇器(Selector)”。

接下來(lái),就可以在你的組件中使用 useBearStore() 了。

你可以引入狀態(tài):

function BearCounter() {
  const bears = useBearStore((state) => state.bears)
  return <h1>{bears} around here...</h1>
}

圖片圖片

也可以引入用于修改狀態(tài)的方法:

function Controls() {
  const increasePopulation = useBearStore((state) => state.increasePopulation)
  return <button onClick={increasePopulation}>one up</button>
}

如此一來(lái),你在 <Controls /> 中調(diào)用修改 increasePopulation() 后,會(huì)觸發(fā) state.bears 的值加 1,接著就能在 <BearCounter /> 中看到新的值了。

圖片圖片

掌握了以上關(guān)于 Zustand 的基本用法后,其實(shí)你就可以開(kāi)發(fā)項(xiàng)目了。

不過(guò),你想更進(jìn)一步提升開(kāi)發(fā)體驗(yàn),那么就要去解決這個(gè)過(guò)程當(dāng)中的一些使用痛點(diǎn)。

其中一個(gè)是關(guān)于更新嵌套狀態(tài)的,這在之前的文章《React 狀態(tài)庫(kù) Zustand 入門教程》[2] 中有提到,有興趣的讀者可以移步閱讀。

不過(guò),我們本次關(guān)注的是另一個(gè)痛點(diǎn):就是從 Store 中獲取狀態(tài)/Action的過(guò)程。

自動(dòng)生成選擇器

按照之前的介紹,在創(chuàng)建完 Store 之后,我們每次都要在組件中這樣去使用:

const bears = useBearStore((state) => state.bears)

我們要使用這種方式從 Store 中提取狀態(tài)或是 Action。

不過(guò)每次頻繁這樣去寫這樣一個(gè)選擇器函數(shù)是很乏味的,這個(gè)時(shí)候我們就可以考慮借助一個(gè)工具函數(shù),對(duì)我們的 Store 進(jìn)行增強(qiáng),支持狀態(tài)/Action的快捷訪問(wèn)。

這就是我們要介紹的 createSelectors(store) 函數(shù)了——先亮代碼:

const createSelectors = (store) => {
  store.use = {}
  for (let k of Object.keys(store.getState())) {
    store.use[k] = () => store((s) => s[k])
  }
  return store
}

代碼量并不多,也好理解。

createSelectors() 接收的 store 就是前一節(jié)的 useBearStore,也就是 create() 的返回值。

createSelectors() 的作用很簡(jiǎn)單,就是向 store 中添加一個(gè) .use 屬性,用于快捷訪問(wèn)其上的內(nèi)容。

當(dāng)然,這里有一個(gè)隱藏的點(diǎn),就是可以通過(guò) store.getState() 拿到當(dāng)前 Store 的所有內(nèi)容。

圖片圖片

接著,修改之前的內(nèi)容——為了便于區(qū)分,我們將原來(lái)的 useBearStore 該名稱 useBearStoreBase 了。經(jīng) createSelectors() 處理后,返回的是 useBearStore。

- const useBearStore = create((set) => ({
+ const useBearStoreBase = create((set) => ({
  // ...
}))

+ const useBearStore = createSelectors(useBearStoreBase)

現(xiàn)在,修改組件中使用 useBearStore 的地方。

function BearCounter() {
-  const bears = useBearStore((state) => state.bears)
+  const bears = useBearStore.use.bears()
  return <h1>{bears} around here...</h1>
}
function Controls() {
-  const increasePopulation = useBearStore((state) => state.increasePopulation)
+  const increasePopulation = useBearStore.use.increasePopulation()
  return <button notallow={increasePopulation}>one up</button>
}

減少了一些代碼量,但是積少成多,也會(huì)提升一些開(kāi)發(fā)體驗(yàn)。

圖片圖片

不過(guò)需要注意的是,每次使用 .use 獲取不管是狀態(tài)還是 Acton 時(shí),都要帶上 () 的調(diào)用后綴。

// 不管是狀態(tài)還是 Action,后面都要帶上 `()`
const bears = useBearStore.use.bears()
const increasePopulation = useBearStore.use.increasePopulation()

當(dāng)然,現(xiàn)在項(xiàng)目中大都使用 TypeScript,為了獲得更好的類型提示,我們對(duì) createSelectors() 進(jìn)行改造,添加類型注解。

import { StoreApi, UseBoundStore } from 'zustand'

type WithSelectors<S> = S extends { getState: () => infer T }
  ? S & { use: { [K in keyof T]: () => T[K] } }
  : never

const createSelectors = <S extends UseBoundStore<StoreApi<object>>>(
  _store: S,
) => {
  let store = _store as WithSelectors<typeof _store>
  store.use = {}
  for (let k of Object.keys(store.getState())) {
    ;(store.use as any)[k] = () => store((s) => s[k as keyof typeof s])
  }

  return store
}

這也是官方給出的方案[3],如果你對(duì) TypeScript 不夠熟悉也沒(méi)關(guān)系,直接將上述代碼貼到項(xiàng)目中使用即可。

總結(jié)

本文我們講解了在使用 Zustand 時(shí)的一個(gè)小優(yōu)化,關(guān)于自動(dòng)生成選擇器。借助 createSelectors(),我們可以更加輕松、快捷的訪問(wèn) Store 中的狀態(tài)或是 Action。

好了,希望本文的內(nèi)容對(duì)你的工作有所幫助。感謝閱讀,再見(jiàn)。

參考資料

[1]Zustand: https://docs.pmnd.rs/zustand

[2]《React 狀態(tài)庫(kù) Zustand 入門教程》: https://juejin.cn/post/7388064351504056335#heading-4

[3]官方給出的方案: https://docs.pmnd.rs/zustand/guides/auto-generating-selectors#create-the-following-function:-createselectors

責(zé)任編輯:武曉燕 來(lái)源: 寫代碼的寶哥
相關(guān)推薦

2010-09-03 09:30:29

CSS選擇器

2012-04-16 14:32:31

iOS選擇器代碼

2024-05-07 13:29:00

CSS選擇器權(quán)重

2021-10-10 19:28:00

Go對(duì)象選擇器

2012-12-27 14:08:39

Android開(kāi)發(fā)顏色選擇器

2011-11-28 13:42:55

Sencha Touc組件選擇器

2017-03-20 14:46:07

Android日期時(shí)間選擇器

2024-04-30 10:59:03

WebSocketCSS選擇器

2023-11-03 11:57:04

2013-03-11 10:30:56

CSSWeb

2022-05-10 07:49:40

CSS選擇器

2009-07-16 11:02:33

Swing文件選擇器

2023-03-16 10:20:55

CSS選擇器

2010-09-07 11:14:32

CSS屬性選擇器CSS

2010-08-26 12:53:40

CSSid選擇器

2010-09-07 11:31:23

CSS派生選擇器CSS

2010-09-06 08:52:00

CSS選擇器

2023-01-30 08:42:33

CSS選擇器性能

2010-08-26 12:47:15

CSSclass

2010-12-27 16:01:45

jQuery選擇器
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 成人在线中文字幕 | 久操亚洲| 亚洲成人av| av毛片在线播放 | 一区二区三区国产好 | 成人a免费 | 精品国产乱码久久久久久牛牛 | 国产高清在线观看 | 日韩中文一区 | 免费的色网站 | 国产精品综合 | 日韩中文在线观看 | 国产91在线 | 中日 | 黄色欧美在线 | 成年人在线观看视频 | 久久精品中文字幕 | 精品久久久久久久久久久院品网 | 伊人网站 | 国产91视频一区二区 | 中文字幕免费在线 | 99精品免费视频 | 亚洲精品一区二区在线观看 | 一级在线观看 | 日韩欧美一区二区三区 | 国产精品高清一区二区三区 | 亚洲精品国产区 | 国产一区二区免费在线 | 狠狠av | 国产精品成人一区二区三区吃奶 | 超碰日韩 | 日韩成人在线网站 | 亚洲第一成人av | 国产一区二区a | 午夜影院黄| 中文字幕在线观看精品 | 日韩二三区 | 精品九九久久 | 欧美国产中文 | 中文字幕一区二区三区不卡 | 一区二区不卡高清 | 黄色免费网站在线看 |