此文主要是我的在使用了 react hooks
一段時間後, 對於 react hooks
的理解,也是一個碎碎念。各位大佬若是以爲有什麼問題能夠提出來討論討論,也接受批評哦~vue
本質上看,好像每個Hooks
都是一個函數吼。react
但,既然是函數,又爲何要另起一個名字(概念)?小程序
因此, 寫/用法上確定會與普通函數有些區別。api
若是說, 咱們如今須要實現一個 TodoList
的增刪需求。咱們能夠函數, 和hooks 分別實現, 而後對比差別。安全
利用閉包,咱們能夠大概實現以下的邏輯塊:閉包
看上面 閉包
和 hooks
分別實現的功能, 貌似也沒啥區別吼。框架
那就繼續往下, 看實際應用到 函數式組件
中的樣子。dom
從上兩個圖能夠發現。return
的jsx
部分徹底相同, 能夠捨去不看。注意力主要放在除了 return
以外的地方(也就是 return
以上的函數體部分)函數
首先咱們看 爲了使用閉包邏輯,而對 組件進行調整的部分。單元測試
由於上圖是結果, 一會兒看可能有些同窗有點蒙, 我將流程拆解下。
第一步、
由於要在組件初始化的時候去建立TodoList
邏輯, 而且將其對外暴露的api進行保存, 因此, 咱們能夠有以下代碼。(一個建立, 一個保存)。
第二步、
接着,咱們就要把數據交給視圖去渲染, 把邏輯交給視圖來觸發了, 該怎麼寫呢, 是這樣嗎?
若是這樣寫,有些同窗可能會發現, 怎麼點擊add
按鈕咋子沒得效果嘞。看邏輯沒得錯啊,用閉包函數提供出來的數據,也用它提供出來的api, 對數據進行增長, 可是爲啥沒得效果嘞!?
介裏, 咱就得提一下關於 函數式組件的更新條件。
useState
返回的setState
函數引發的state
變動,則會去引發當前組件的 rerender
;props
變動,也會引發組件的 rerender
;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 功能。而視圖則是側重在固定的數據, 是否有固定的視覺呈現。(這個的前置條件就得是 視圖與邏輯的分離)
若是說, 咱們有一個產品, 分爲 PC端、H5端、RN端、Taro小程序端。 那是否能讓這些不一樣端都共享同一套業務邏輯代碼?
線上代碼連接點擊這裏
以上基本全是本人在使用了 hooks 一段時間後的, 對於hooks 的理解, 以及對一些實踐方式的猜測。
也歡迎各位大佬一塊兒來參與討論。