Hook

簡介
  • HookReact 16.8 的新增特性。它可以讓你在不編寫 class 的情況下使用 state 以及其他的 React 特性

  • 其實就是專門用于增強函數(shù)組件的功能的,使之盡可能的替代類組件而存在

  • 本質(zhì)上是一個函數(shù)(use...),可掛載任何功能

  • 僅在函數(shù)組件體內(nèi)生效

State Hook
  • useState(defaultState);

  • 參數(shù)為默認的 state

  • 返回一個長度為 2 的數(shù)組,第一項是 state 值,第二項為改變 state 值的函數(shù),const [count, setCount] = useState(0);

  • 狀態(tài)可以有多個

State Hook原理
  • 函數(shù)組件的首次調(diào)用以及后續(xù)更新都會直接調(diào)用use...函數(shù)

  • React 通過函數(shù)組件節(jié)點的狀態(tài)表格來保存 state 值,使其不會在每次組件函數(shù)調(diào)用時都會被初始化

  • 首次調(diào)用函數(shù)組件時這些 state 值會被按順序保存在狀態(tài)表格中,每個 state 值都有一個固定且唯一的下標(biāo)值,從 0 開始

  • 更新函數(shù)組件時,將會忽略默認 state 值,直接通過對應(yīng)下標(biāo)值找到狀態(tài)表格中所保存的值

  • 這也是 React 解釋說為什么使用 useState 而不是 createState 命名的原因

State Hook注意點
  • useState 不可寫在代碼塊之中,例如判斷,循環(huán)。因為這可能導(dǎo)致更新函數(shù)組件時,一些 useState 不被執(zhí)行之類的混亂情況,從而導(dǎo)致下標(biāo)值對應(yīng)錯誤,state 被賦予不正確的值

  • useState 所返回的第二項函數(shù),引用不會改變,節(jié)省內(nèi)存

  • set...函數(shù)的執(zhí)行會使函數(shù)組件重新渲染,也就是再次執(zhí)行函數(shù)

    • 若調(diào)用改變 state 值的函數(shù)set...state 的值與之前的完全相同(使用Object.is判斷),則不會導(dǎo)致重新渲染

    • 調(diào)用改變 state 值的函數(shù) set... 會直接替換原先的值,而不是合并覆蓋,所以要注意引用值的使用,可使用 ...展開

  • 函數(shù)組件內(nèi)的強制刷新可使用 const [, forceUpdate] = useState({}); forceUpdate({}); 調(diào)用時發(fā)現(xiàn)對象地址不同,則會重新渲染該函數(shù)組件

  • 如果某些狀態(tài)之間并沒有什么必然的聯(lián)系,我們應(yīng)該將他們分開來寫,而不是混合到一個 state

  • 和類組件相同,函數(shù)組件中的狀態(tài)改變?nèi)羰窃?DOM 事件中則是異步的,這種情況下多次調(diào)用狀態(tài)變化函數(shù)會被合并來提高效率

  • 若是想要在 DOM 事件中多次調(diào)用狀態(tài)變化函數(shù),可以傳入一個函數(shù)作為參數(shù)

  • setCount(prevC => prevC + 1); setCount(prevC => prevC + 1);

  • 這些函數(shù)會在 DOM 事件結(jié)束時依次執(zhí)行,前一個函數(shù)的返回值作為后一個函數(shù)的參數(shù)

Effect Hook
  • 用于在函數(shù)組件內(nèi)處理副作用

  • useEffect(),該函數(shù)接收一個函數(shù)參數(shù),函數(shù)內(nèi)部就是我們要執(zhí)行的副作用代碼

副作用
  • ajax 請求,計時器,其他異步操作,更改真實 DOM 對象,本地存儲,其他會對外部產(chǎn)生影響的操作
Effect Hook注意點
  • 副作用函數(shù)(useEffect的函數(shù)參數(shù))的運行時間點,位于更改了真實 DOM 之后,且已經(jīng)完成重新渲染,也就是用戶已經(jīng)看到了頁面變化之后,所以是異步執(zhí)行,不會阻塞

  • 而類組件中的 componentDidMount 以及 componentDidUpdate 的執(zhí)行時間點位于更改了真實 DOM 之后,但還未重新渲染,也就是用戶還未看到頁面變化之前

  • useEffect 在一個函數(shù)組件內(nèi)可多次使用,但不可寫入代碼塊之中,例如判斷,循環(huán)。與 useState 同理

  • 副作用函數(shù)可以有一個返回值,返回值必須為函數(shù)或默認的undefined,該函數(shù)作用為清理遺留的副作用,例如計時器,運行時間點位于下次副作用函數(shù)運行之前,所以首次渲染組件不會運行,useEffect 函數(shù)的第二個參數(shù)未變化時也不會運行,組件被銷毀時一定會運行

  • useEffect 函數(shù)可接受第二個數(shù)組參數(shù),數(shù)組中傳入該副作用函數(shù)內(nèi)的依賴數(shù)據(jù)

    • 當(dāng)組件重新渲染后,只有依賴數(shù)據(jù)與上次不同時,才會再次執(zhí)行副作用函數(shù)

    • 所以若使用空數(shù)組作為useEffect 函數(shù)的第二個參數(shù),那么副作用函數(shù)僅在首次渲染結(jié)束后運行一次,清理函數(shù)也僅在卸載時運行一次

  • 副作用函數(shù)中,若使用了組件函數(shù) AO 中的變量,則由于閉包的原因,會導(dǎo)致副作用函數(shù)中變量不會實時變化,而是使用所在的某次組件函數(shù)的調(diào)用時的變量

自定義Hook
  • 參考

  • 將一些常用的,多個組件都會使用的Hook功能,抽離出去寫成一個函數(shù),就叫做自定義Hook

  • 組件在使用自定義Hook時就等同于將自定義Hook函數(shù)中的代碼拿出來放到該自定義Hook函數(shù)執(zhí)行的地方

    • 所以自定義Hook中使用set...同樣會使自定義Hook函數(shù)本身以及使用她的函數(shù)組件都重新執(zhí)行一次

    • 并且執(zhí)行順序也是從函數(shù)組件開始,遇到自定義Hook執(zhí)行就進入自定義Hook函數(shù)內(nèi)部執(zhí)行,執(zhí)行結(jié)束返回新的值賦值給接收的變量,最后就是函數(shù)組件剩余的代碼執(zhí)行

  • 自定義Hook必須以use開頭

  • 自定義Hook中的state始終是獨立的,所以在兩個組件中使用相同的 Hook 也不會共享 state

Context Hook
  • 參考

  • 用于函數(shù)組件更輕松的獲取context

  • 在消費組件中

    • const myContext = useContext(MyContext);
Callback Hook
  • 參考

  • 返回一個僅根據(jù)依賴項變化而變化地址的函數(shù),常用于給純組件傳遞屬性方法

Memo Hook
  • 參考

  • 返回第一個函數(shù)參數(shù)的返回值,僅在依賴項變化時才會再次執(zhí)行第一個函數(shù)參數(shù),返回一個新的值

  • 常用于高開銷的計算操作

Ref Hook
  • 參考

  • 讓函數(shù)組件重新執(zhí)行時不會又重新創(chuàng)建一個新的ref

  • 也就是讓每個函數(shù)組件對象擁有一個固定不變的ref

  • 通過.current來獲取,不局限于獲取dom元素或組件對象

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容