為何要使用React Hooks?

在了解React Hooks之前,我們必須先知道React的函數(shù)組件性質(zhì)以及的函數(shù)組件為什么要用Hooks。

大伙兒都知道,無組件不React,而React的組件又分為類式組件和函數(shù)式組件,為什么函數(shù)式組件大受React開發(fā)者的推廣?

首先我們從源碼的角度來簡(jiǎn)單談一下類式組件和函數(shù)式組件的區(qū)別:

定義類組件時(shí),我們必須繼承React.Component

放一個(gè)簡(jiǎn)單的React類式組件實(shí)例

同時(shí),它具有一個(gè)render函數(shù)

ReactDOM會(huì)被Component引入

咱們見好就收,畢竟具體操作需要涉及源碼,不是一時(shí)半會(huì)解釋的清的。那么render加載組件時(shí),發(fā)生了什么?

1.根據(jù)組件標(biāo)簽,找到組件

2.由于是類式組件,創(chuàng)建新的實(shí)例,并通過該實(shí)例調(diào)用到原型上的render方法

3.將虛擬Dom轉(zhuǎn)化為真實(shí)DOM

類式組件被定義為復(fù)雜的組件,這不是React所希望的,React想要的組件是純函數(shù)組成的管道,那么便引出了作為簡(jiǎn)單組件的函數(shù)組件。

而函數(shù)組件作為一個(gè)函數(shù),是沒有繼承React.Component的,他只需要兩步1.找到組件 2.渲染組件,所以也就不存在生命周期,以及狀態(tài)及this。

這就意味著,函數(shù)組件實(shí)現(xiàn)有關(guān)state的管理,需要借助redux,秉承redux能不用就不用的準(zhǔn)則(其實(shí)有的時(shí)候還蠻香的,全局管理方便),往往會(huì)另功能簡(jiǎn)單的React組件變得笨重。

于是React團(tuán)隊(duì)自16.8版本以來,推出了穩(wěn)定的React HOOKS來解決上述問題。


React Hooks

React約定鉤子的前綴為use,所以需要自定義鉤子時(shí),一般使用use為前綴創(chuàng)建鉤子。除此之外,React默認(rèn)提供了四種鉤子:

1)useState

相當(dāng)于一種靜態(tài)聲明,目的是引入狀態(tài),此時(shí)的鉤子保存狀態(tài)。useState()接收函數(shù)狀態(tài)的初始值,具有兩個(gè)參數(shù),第一個(gè)為狀態(tài)變量,第二個(gè)為改變狀態(tài)的方法,比如const [number,setNumber] = useState(0)

2)useEffect

副作用鉤子,用來替代生命周期,最常見是向服務(wù)器請(qǐng)求數(shù)據(jù)

比如這一個(gè)例子

useEffect()作為常用的鉤子之一,接收兩個(gè)參數(shù),第一個(gè)參數(shù)是函數(shù),第二個(gè)參數(shù)是一個(gè)數(shù)組,給出依賴項(xiàng),數(shù)組里的值代表需要監(jiān)測(cè)的對(duì)象。

問題來了,生命周期那里體現(xiàn)?

當(dāng)組件參數(shù)發(fā)生改變時(shí),useEffect()就會(huì)執(zhí)行。組件第一次渲染時(shí),useEffect()也會(huì)執(zhí)行。是不是相當(dāng)于生命周期中的componentDidMount()呢?而useEffect()下的return,一般寫在第一個(gè)參數(shù)的異步操作后,相當(dāng)于componentWillUnmount(),在組件卸載前執(zhí)行,做收尾工作。

3)useReducer

屬于action鉤子,useReducer()將算出新的state,返回一個(gè)數(shù)組。例如const [state, dispatch] = useReducer(ReducerFunc, initState)

第一個(gè)值是當(dāng)前狀態(tài)值,第二個(gè)值是發(fā)送action的dispatch。與Redux的Reducer一樣,能夠共享狀態(tài),但是不同之處是沒法提供中間件和時(shí)間旅行(time travel)。

4)useContext

共享狀態(tài)的一個(gè)鉤子,在組件外部建立一個(gè)Context,包裹組件時(shí),可以將被包裹組件的狀態(tài)共享給組件內(nèi)部調(diào)用的其他組件,即:

1.外部建立Context()

2.包裹含有狀態(tài)的組件1

3.在其他函數(shù)組件內(nèi)部調(diào)用該Context()時(shí),可以將組件1的狀態(tài)共享

但是有一點(diǎn)需要注意的是,使用useContext進(jìn)行的數(shù)據(jù)流管理,每當(dāng)context更新時(shí),所有使用到該context的組件都會(huì)重新渲染。所以需要方法對(duì)useContext()進(jìn)行優(yōu)化,減少不必要的更新,優(yōu)化方法可以參考:如何優(yōu)雅地處理使用React Context 導(dǎo)致的不必要渲染問題?

除此之外還有一些自帶的鉤子,比如:

5)useCallback和useMemo

可以用做React性能優(yōu)化

react很煩,一但更新數(shù)據(jù),render依次diff刷新節(jié)點(diǎn),攔都攔不住。useCallback和useMemo就是攔住他刷新的方法。

假設(shè)React組件中有個(gè)button,同時(shí)聲明了click方法,每次render時(shí),button和click方法都會(huì)重新render。于是可以使用useCallback(),避免組件重復(fù)無意義的渲染。

比如:

useCallback應(yīng)用舉例

原因是緩存了相同的引用,以此避免了無效render。

useMemo參數(shù)用法一致,不過useCallback一般用于緩存函數(shù),useMemo用于緩存計(jì)算結(jié)果之類。

useCallback(fn, deps)相當(dāng)于useMemo(()=>fn, deps)

*可以推出,使用useCallback實(shí)現(xiàn)useMemo的方法:

useMemo(fun,...deps)??

useCallback(fun(...deps), [...deps])

這兩者是等價(jià)的。


如果有不一樣的理解,有交流想法的朋友可以聯(lián)系私信,轉(zhuǎn)載請(qǐng)做好來源說明!

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

相關(guān)閱讀更多精彩內(nèi)容

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