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