小盧碎碎念之 React Hooks

此文主要是我的在使用了 react hooks 一段時間後, 對於 react hooks 的理解,也是一個碎碎念。各位大佬若是以爲有什麼問題能夠提出來討論討論,也接受批評哦~vue

是什麼

本質上看,好像每個Hooks都是一個函數吼。react

但,既然是函數,又爲何要另起一個名字(概念)?小程序

因此, 寫/用法上確定會與普通函數有些區別。api

與普通函數的異同

若是說, 咱們如今須要實現一個 TodoList 的增刪需求。咱們能夠函數, 和hooks 分別實現, 而後對比差別。安全

實現簡單TodoList

利用閉包

利用閉包,咱們能夠大概實現以下的邏輯塊:閉包

使用Hooks

看上面 閉包hooks 分別實現的功能, 貌似也沒啥區別吼。框架

那就繼續往下, 看實際應用到 函數式組件 中的樣子。dom

閉包邏輯在函數式組件中的使用

Hooks 在函數式組件中的使用

從上兩個圖能夠發現。returnjsx 部分徹底相同, 能夠捨去不看。注意力主要放在除了 return 以外的地方(也就是 return 以上的函數體部分)函數

首先咱們看 爲了使用閉包邏輯,而對 組件進行調整的部分。單元測試

由於上圖是結果, 一會兒看可能有些同窗有點蒙, 我將流程拆解下。

第一步、

由於要在組件初始化的時候去建立TodoList邏輯, 而且將其對外暴露的api進行保存, 因此, 咱們能夠有以下代碼。(一個建立, 一個保存)。

第二步、

接着,咱們就要把數據交給視圖去渲染, 把邏輯交給視圖來觸發了, 該怎麼寫呢, 是這樣嗎?

若是這樣寫,有些同窗可能會發現, 怎麼點擊add 按鈕咋子沒得效果嘞。看邏輯沒得錯啊,用閉包函數提供出來的數據,也用它提供出來的api, 對數據進行增長, 可是爲啥沒得效果嘞!?

介裏, 咱就得提一下關於 函數式組件的更新條件。

  1. 組件內部使用useState返回的setState 函數引發的state 變動,則會去引發當前組件的 rerender ;
  2. 組件外部傳入的 props 變動,也會引發組件的 rerender;
  3. 第三個就是 useContext 了,當前組件使用的上下文中, 只要有一條數據變動, 就會引發該組件的 rerender (context 仍是得拆分的細一點 =.=)

更新條件介紹完畢, 回到主題, 好像咱們更改閉包函數內部數據, 一個條件都沒和上面三個吻合的, 因此, 咱們得想個辦法,每次更新了數據後,讓函數式組件去 rerender

而這裏就選用的第一種, 更新state來引發組件的rerender

說幹就幹, 首先,在組件內部增長一個 useState 來記錄 list , 而後在每次對閉包函數內部的 list 進行增、刪後, 都去獲取最新值,並更新到視圖上。

寫完是這個樣子啦, 而後去運行一下。。 。 沒得問題, 美滋滋, 打卡下班,多麼充實的一天~~~

直至N天后, 某個同事小吳要用到這個功能, 聽着你給他講, 要這麼這麼用, 要記錄什麼什麼 state, 小吳怕是都要按不住手中的刀了。因此, 爲了咱們的生命安全, 咱們要儘可能的站在小吳的角度,去考慮如何將一個功能更加內聚, 對外部的使用要求更小

此時, 也該 react hooks 閃亮登場了(廢話了這麼多, 幹)

去除 return 部分, 咱們發現咱們要用 TodoList 的邏輯, 只須要增長如下一行

有點蒙?我再把 useTodoList 的代碼拿過來

還有在組件中的使用

怎麼樣, 是否是很簡潔。哈哈哈哈。

接下來咱們大概走一下這個hooks 的邏輯。

useTodoList 內部, 有記錄一個 list 。以及有兩個函數, 分別對list進行增長和刪除。最後將 list,增長和刪除邏輯return出去。而後外部組件中又去調用這增長刪除邏輯, 修改了 hooks 中的數據, 然又引發外部組件的rerender

而此時, 則又涉及到了一個更新條件, 上面講的三條函數式組件的更新條件, 此時也就得多加一條了

​ 4. 函數式組件中所用到的 hooks 中, 若是更新了 state, 則會依次由上往下(hooks 書寫順序),由內往外的觸發 hooks函數式組件rerender

由此條件, 咱們才能在 hooks 中的數據變動的時候引發外部的視圖更新。

其實, hooks 我的感受跟 函數式組件同樣, 只不過hooks 拋出的是API,是一些邏輯處理函數。 而函數式組件拋出的是 Fiber Node, 是將要渲染到視圖上的東西。

另外的, 提及hooks 和 閉包函數差別,hooks 內部能夠用其餘hooks, 以及經過 useEffect 來實現的一些 生命週期之類, 閉包函數則不行, 閉包函數要強行作, 還得外部去調用,那樣對外部的要求又高了, 小吳的刀怕是兩我的都按不住了。

因此,對於這個主題, hooks 與普通函數的異同, 總的來講

  • hooks呢, 可使用 其餘的 hooks , 用法跟函數式組件 一致, 只不過return的不是JSX, 而是一些 API 或者數據。固然這裏講的只是輸出, 還有輸入的, 如 useTodoList(['666']) 這種的

  • 對於函數, 咱們能夠利用閉包現象,來寫一段內聚的邏輯,而後暴露一些API給外部來操控內部的數據和邏輯。

可是 hooks 要求相對於閉包函數較高, 得運行在 react 環境中, 或者 vue3?(vue3 的 Composition API 對應 react 的話,應該就是 react hooks)vue3的還不太清楚 hooks 寫法是否和 react 的一致,若是一致的話, 是否是一個 hooks 就能夠在兩個框架中共用?

插一句

接下來基本都是個人猜測, 沒得實踐過,你們能夠來討論討論。

能夠作什麼

上面一點有講到

hooks 我的感受跟 函數式組件同樣, 只不過hooks 拋出的是API,是一段邏輯。 而函數式組件拋出的是 Fiber Node, 是將要渲染到視圖上的東西。

因此, 針對一些比較複雜且公共的邏輯, 咱們就能夠將邏輯封裝成一個自定義hooks。供不一樣UI來共享該邏輯。

若是激進一點, 咱們能夠將 視圖 和 邏輯徹底的分離, 一個組件分紅兩個, 一個邏輯的 hooks , 一個視圖的 template, 可是感受這樣寫好像變成了Vue, 幹, 具體仍是得去實踐,看有啥優缺點。

單元測試

單元測試分 功能測試 和 UI測試。

功能測試對應 Hooks 的測試, 測試該 hooks 的邏輯是否正常。

UI測試對應 template 的測試, 測試輸入固定數據, 視圖有沒有正確的渲染出來。

由 數據驅動視圖( UI = render(State) ) 這一理念,咱們對於一個功能的測試, 徹底能夠將重心放在 hooks 上, 對於 dom 的測試, 只須要測試數據有無正確渲染就行。而不須要 各類獲取 dom,觸發這個那個事件,事件裏又去觸發對應邏輯。

抽象來看, 咱們測試一塊地方的功能, 分兩層, 一層視圖, 一層邏輯。 咱們與視圖的交互,目的就是爲了去觸發某個邏輯。 視圖只是用戶與邏輯之間的一個媒介而已。因此測試的話, 我以爲能夠繞過繁瑣的視圖層操做。直接測試 hooks 功能。而視圖則是側重在固定的數據, 是否有固定的視覺呈現。(這個的前置條件就得是 視圖與邏輯的分離)

純JS/TS業務邏輯共用

若是說, 咱們有一個產品, 分爲 PC端、H5端、RN端、Taro小程序端。 那是否能讓這些不一樣端都共享同一套業務邏輯代碼?

寫在最後

線上代碼連接點擊這裏

以上基本全是本人在使用了 hooks 一段時間後的, 對於hooks 的理解, 以及對一些實踐方式的猜測。

也歡迎各位大佬一塊兒來參與討論。

相關文章
相關標籤/搜索