您好,登錄后才能下訂單哦!
本篇內(nèi)容介紹了“如何掌握Hooks”的有關(guān)知識,在實(shí)際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
回想下你入門Hooks的過程,是不是經(jīng)歷過:
類比ClassComponent的生命周期,學(xué)習(xí)Hooks的執(zhí)行時機(jī)
慢慢熟練以后,發(fā)現(xiàn)Hooks的執(zhí)行時機(jī)和生命周期又有些不同。比如componentWillReceiveProps對應(yīng)哪個Hooks?
感到困惑,去搜一些Hooks原理層面的文章閱讀
作為一個API,不該簡簡單單、可可愛愛的照著文檔調(diào)用就行么,Hooks為什么這么難?
React官方也發(fā)現(xiàn)了這個問題,在React要重寫文檔了講到,React要基于Hooks重寫文檔。
本文主要包括2方面內(nèi)容:
解釋Hooks難學(xué)的原因
給出學(xué)習(xí)Hooks的建議
React的底層架構(gòu)
可以用一個公式概括React:
const UI = fn(state);
視圖可以看作狀態(tài)經(jīng)過函數(shù)的映射。
用戶與界面的交互,可以看作這個公式的不斷執(zhí)行。
這個公式太精簡了,沒有解釋state(狀態(tài))從哪兒來,我們擴(kuò)展下:
const state = reconcile(update); const UI = fn(state);
鴻蒙官方戰(zhàn)略合作共建——HarmonyOS技術(shù)社區(qū)
用戶交互產(chǎn)生update(更新)
update經(jīng)過reconcile步驟計(jì)算出當(dāng)前應(yīng)用的state
fn將state映射為視圖變化(UI)
我們給fn起個名字:commit:
const state = reconcile(update); const UI = commit(state);
那么update在哪里產(chǎn)生呢?當(dāng)然來自于用戶交互,比如:點(diǎn)擊事件。
所以React的底層架構(gòu)可以簡化為三步:
用戶交互產(chǎn)生update
state = reconcile(update);
UI = commit(state);
了解了底層架構(gòu),我們再來看通過類比ClassComponent學(xué)習(xí)Hooks會帶來的問題。
生命周期函數(shù)的抽象層級
我們已經(jīng)有了完整的驅(qū)動視圖更新的底層架構(gòu),開發(fā)者該怎么操作這套架構(gòu)呢?
可以用計(jì)算機(jī)的抽象層級來類比:
高層:應(yīng)用程序 中層:操作系統(tǒng) 底層:計(jì)算機(jī)組成架構(gòu)
對應(yīng)React:
高層:應(yīng)用程序 ClassComponent生命周期 中層:操作系統(tǒng) 介入架構(gòu)的API 底層:計(jì)算機(jī)組成架構(gòu) React底層架構(gòu)
可以看到,生命周期函數(shù)屬于抽象程度比較高的層次。這么設(shè)計(jì)也是為了讓開發(fā)者更容易上手React。
設(shè)想一個Vue2開發(fā)者要轉(zhuǎn)React技術(shù)棧,只需要類比Vue的生命周期來學(xué)習(xí)React的生命周期就行了。
這一切在Hooks到來前都沒問題,然而......
Hooks的抽象層級
Hooks屬于中等抽象層級。也就是說,Hooks直接介入底層架構(gòu)的運(yùn)行流程。
高層:應(yīng)用程序 中層:操作系統(tǒng) Hooks 底層:計(jì)算機(jī)組成架構(gòu) React底層架構(gòu)
當(dāng)我們用生命周期函數(shù)來類比Hooks時,其實(shí)是用高抽象層級的事物來描述低抽象層級的事物。
動物 --> 哺乳動物 --> 牛 --> 奶牛
對于一個只見過奶牛,再沒見過其他動物的人,你怎么向他解釋哺乳動物是啥?
正是由于抽象層級的不對稱,造成通過生命周期函數(shù)類比學(xué)習(xí)Hooks會遇到問題。
該怎么學(xué)Hooks
既然Hooks屬于中等抽象層,離底層很近,那么更好的學(xué)習(xí)方式是通過底層向上學(xué)習(xí)。
祭出我們的三步公式:
用戶交互產(chǎn)生update
state = reconcile(update);
UI = commit(state);
對照公式,我們來講解幾個常見hook的工作流程:
useState
舉個例子:
function App() { const [state, updateState] = useState(0); return <div onClick={() => updateState(state + 1)}></div>; }
useState返回值數(shù)組包含:
保存的state
改變state的方法updateState
對照公式,state屬于公式步驟2計(jì)算得出的:
state = reconcile(update);
此時視圖還沒有更新。
用戶點(diǎn)擊div觸發(fā)updateState,對應(yīng)公式步驟1:
用戶交互產(chǎn)生update
所以調(diào)用updateState能開啟底層架構(gòu)的三步運(yùn)行流程。
當(dāng)reconcile計(jì)算出state后就會進(jìn)入第三步:
UI = commit(state);
最終渲染視圖。
useEffect
舉個例子:
useEffect(doSomething, [xx, yy])
useEffect的回調(diào)函數(shù)doSomething在第三步執(zhí)行完成后異步調(diào)用:
UI = commit(state);
所以在doSomething函數(shù)內(nèi)部能獲取到完成更新的視圖。
第二個參數(shù)[xx, yy]作為依賴項(xiàng),決定了doSomething是否會被調(diào)用。
useLayout
Effect不同于useEffect在第三步執(zhí)行完成后異步調(diào)用,useLayoutEffect會在第三步執(zhí)行完UI操作后同步執(zhí)行。
useRef
以上例子可以看到,useState與useEffect分別在三步流程的不同步驟被觸發(fā),他們的觸發(fā)時機(jī)是確定的。
那么這三個步驟如何交流呢?通過useRef。
useState作用于第一、二步,useLayoutEffect作用于第三步,useEffect作用于第三步完成后。
使用useRef,就能達(dá)到在不同步驟間共享引用類型數(shù)據(jù)的目的。
可以看到,React為底層架構(gòu)三步工作流程的每一步提供了對應(yīng)的hook,同時提供了串聯(lián)這三步工作流程的hook。
開發(fā)者只需要根據(jù)業(yè)務(wù)需要,通過基礎(chǔ)Hooks組裝出自定義hook,就能在底層架構(gòu)運(yùn)行流程的各個時期運(yùn)行邏輯。
自底向上學(xué)習(xí)是本末倒置么?
有同學(xué)會反駁:之前學(xué)React得學(xué)生命周期函數(shù)的執(zhí)行時機(jī),現(xiàn)在學(xué)Hooks得學(xué)底層架構(gòu)運(yùn)行流程。難道不是本末倒置,更復(fù)雜了么?
其實(shí)不然。我問你幾個問題:
componentWillReceiveProps為什么被標(biāo)記為unsafe?
getDerivedStateFromProps用過么?
this.setState是同步還是異步的?
這些和生命周期函數(shù)相關(guān)的問題一點(diǎn)都不簡單!很多用了幾年React的前端不一定回答的上。
作為高層次抽象,生命周期函數(shù)隱藏了太多實(shí)現(xiàn)細(xì)節(jié)。同時React又太靈活,不像Vue通過模版語言限制了開發(fā)者的操作。
結(jié)果就是:不同React開發(fā)者寫出各種奇奇怪怪的ClassComponent。
反觀通過底層架構(gòu)運(yùn)行流程學(xué)習(xí)Hooks:
底層架構(gòu)運(yùn)行流程就是React的絕對真理,不會隱藏更多抽象
Hooks的寫法規(guī)范限制了開發(fā)者的奇葩操作
這里唯一的問題,就是缺少一份從底層出發(fā)的文檔。這也是官方要重寫文檔的初衷。
“如何掌握Hooks”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。