30行代碼,實現(xiàn)超火狀態(tài)管理工具 Zustand(43k star)
zustand
zustand 是一個 React 的輕量級狀態(tài)管理工具庫,用起來非常方便,不僅支持多模塊創(chuàng)建狀態(tài)管理,還可以使用 hook + selector 的方式,在組件內(nèi)去獲取所需的狀態(tài)變量,我個人是感覺跟 Vue Pinia 有點相似,以下是一個簡單的小例子,展示 zustand 的基本使用~
點擊按鈕的時候,會通過 increase方法去修改狀態(tài)管理內(nèi)部的 count。
按需重渲染
什么是按需重渲染?就比如當(dāng) count 變化時,只有需要使用到 count 的組件才會重新渲染,沒用到 count 的就不用重渲染,減少不必要的渲染~
就比如我按了按鈕之后,只有 Counter 這個組件會重渲染,而 App 卻不會:
因為 count 只被 Counter 組件所選擇到了,所以當(dāng)count變化時,Counter 會重渲染:
源碼實現(xiàn)
實現(xiàn) create:
我們可以借著上面的代碼例子,來一步步實現(xiàn) zustand 的源碼,先把引入的代碼給注釋掉,接下來我們自己來實現(xiàn) create。
其實 zustand的源碼量非常至少,并且也很容易讀懂,無非就分成幾步:
(1) 聲明一個 create 函數(shù),用來創(chuàng)建狀態(tài)管理
(2) 維護一個狀態(tài)管理 state,用來存放狀態(tài)變量
(3) 聲明兩個函數(shù) set、get,一個是設(shè)置
(4) 維護一個訂閱集合 subscribe,收集訂閱方,且當(dāng) set的時候,通知 subscribe 中的所有訂閱方
(5) 準備一個 hooks 返回給使用者,并且需要準備一些材料,包括set、get、訂閱入口
以上就實現(xiàn)了 create這個函數(shù)~
實現(xiàn) _useStore
接下來實現(xiàn) _useStore,其實他就做一件事:對比一下被選擇的值,對比他修改前后是否相等,不相等的話就強制重渲染本組件。
強制重渲染可以巧妙借助useReducer這個內(nèi)置 hooks 來實現(xiàn)::
達到效果
現(xiàn)在已經(jīng)達到了我們想要的效果了~
并且當(dāng) count 變化時,也只會重渲染 Counter 組件~
代碼優(yōu)化
其實 _useStore的代碼還可以再優(yōu)化一些,我們可以借助 React 的內(nèi)置 hooks,useSyncExternalStore 來簡化我們的代碼
這個 hooks 會自動傳一個比較函數(shù)給 subscribe,并且第二個參數(shù)函數(shù)返回的值改變時,會觸發(fā)這個比較函數(shù)~