從 custom Hooks 到 shared Hooks :hox 原理分析

本文旨在用盡量通俗易懂的方式講清楚 hox 在底層是如何實現的,也所以可能在某些方面的表述不夠嚴謹,若有偏頗,還請各位讀者多多指正。

Hox 是下一代的 React 狀態管理器,關於它的更多介紹能夠參考這篇文章,本文假設你已經對 hox 的用法有了初步的瞭解。git

在 hox 中,咱們但願能充分發揮 React Hooks 的特性,也但願讓全局狀態和組件內部狀態的編寫體驗保持一致,因此咱們使用 custom Hook 的方式定義 model 的邏輯。github

咱們不妨先來看下一個普通的 custom Hook 是什麼樣的效果吧:segmentfault

export function useFoo() {
  const [count, setCount] = useState(0)
  function increment() {
    setCount(count + 1)
  }
  return {
    count,
    increment,
  }
}

咱們能夠在組件中調用 useFooapp

export function ComponentA() {
  const foo = useFoo()
  return (
    <div>
      <p>{foo.count}</p>
      <button onClick={foo.increment}>Increment</button>
    </div>
  )
}

不難發現,咱們經過定義 custom Hook ,對邏輯進行了一層封裝,也讓組件變得更加簡潔。然而,若是此時咱們再建立一個 B 組件:spa

export function ComponentB() {
  const foo = useFoo()
  return (
    <div>
      <p>{foo.count}</p>
    </div>
  )
}

當咱們點擊 A 組件中的 Increment 按鈕時,B 組件中的數字會跟着變化麼?
答案天然是不會的,由於 useFoo 這個 custom Hook 雖然實現了邏輯的封裝複用,可是卻並不能讓數據共享code

而 hox ,就是爲了解決這個問題而生。cdn

咱們不妨接着上面的例子,使用 hox 提供的 createModeluseFoo 進行一層封裝:blog

const useFooModel = createModel(useFoo)

createModel 會建立一個 Executor 組件的實例,並在其中執行 useFoo 這個 Hook ,並把 useFoo 的執行結果保存起來。最後,它會返回一個新的 Hook: useFooModel 。乍一看, createModel 和 HOC (高階組件)甚至有幾分神似。jsx

不一樣於 useFoo ,在調用 useFooModel 時,咱們並非真的執行了 useFoo 這個 custom Hook ,而是向 Executor 組件進行數據的訂閱。也就是說,若是咱們在多個組件中都調用了 useFooModel ,那它們所拿到的數據其實是同一份,更準確的說,它們拿到的那份數據,就是存在 Executor 中的那份 staterem

經過這種方式,咱們讓 custom Hook 能夠作到數據的共享,這也是 createModel 之因此叫作 createModel 的緣由:經過它,咱們把一個 custom Hook 變成了一個全局的 model 。

如今,咱們再來更新一下剛纔的例子:

export function ComponentA() {
  const foo = useFooModel() // 這裏從 useFoo 變成了 useFooModel
  return (
    <div>
      <p>{foo.count}</p>
      <button onClick={foo.increment}>Increment</button>
    </div>
  )
}

export function ComponentB() {
  const foo = useFooModel() // 這裏從 useFoo 變成了 useFooModel
  return (
    <div>
      <p>{foo.count}</p>
    </div>
  )
}

如今,A B 兩個組件都獲取到了 Executor 中的那份數據,而且訂閱了它將來的更新。所以當咱們點擊組件 A 的 Increment 按鈕時,咱們其實是觸發了 Executor 組件中的一個 setState ,而後 Executor 組件進行重渲染,通知它的訂閱者們。A 組件和 B 組件收到了更新通知和新的數據,也會跟着從新進行渲染。最終咱們能夠看到,A B 兩個組件顯示的數字都變成了 1

若是你但願對 hox 有更多的瞭解的話,不妨在 GitHub 上閱讀它的源碼,或是親自體驗一下~

相關文章
相關標籤/搜索