React中useLayoutEffect鉤子使用場(chǎng)景詳解
簡(jiǎn)介
不久前,React對(duì)其功能組件進(jìn)行了一次重大更新(在2019年3月的16.8版本中),終于為這些組件提供了一種變得有狀態(tài)的方法。
鉤子的加入不僅意味著功能組件將能夠提供自己的狀態(tài),而且還能通過(guò)引入useEffect鉤子來(lái)管理自己的生命周期事件。
此外,這次更新還引入了一個(gè)全新的useLayoutEffect鉤子,根據(jù)React文檔,它的作用與[useEffect](upmostly.com/tutorials/i… in a new tab)鉤子的作用相當(dāng)相似;所以這就引出了一個(gè)問題。 兩者之間到底有什么區(qū)別?
如果你對(duì)鉤子還不熟悉,我建議你去看看 這篇文章在那里你會(huì)很好地了解它們是什么,它們的用途,以及你如何在你的應(yīng)用程序中使用它們。
在這篇文章中,我們將更深入地探討每個(gè)鉤子的作用,兩者之間的區(qū)別是什么,到最后,你應(yīng)該對(duì)它們各自的工作原理有更好的理解,什么時(shí)候應(yīng)該使用其中一個(gè)而不是另一個(gè),以及愛上其中一個(gè)的一些常見陷阱。
useEffect鉤子的概述
這個(gè)鉤子最初是作為處理功能組件中的副作用的另一種方式添加的,類似于基于類的組件中的componentDidMount和componentDidUpdate方法(它們也是在同一時(shí)間運(yùn)行的)。
因此,它在基于類的組件中的等價(jià)物是componentDidMount、componentDidUpdate 和 componentWillUnmount方法的組合,后者是作為參數(shù)傳遞給鉤子的回調(diào)語(yǔ)句中的一個(gè)效果。
鉤子流程
- 你以某種方式引起渲染(狀態(tài)被更新或父類重新渲染)。
- React渲染你的組件(調(diào)用它)
- 屏幕得到視覺上的更新
- 然后運(yùn)行useEffect
useLayoutEffect鉤子的概述
與useEffect類似,它與Class Components中的componentDidMount和componentDidUpdate同時(shí)運(yùn)行。然而,useLayoutEffect是同步運(yùn)行的,與useEffect相反,這意味著它收到的回調(diào)只有在組件中進(jìn)行了V-DOM計(jì)算之后,但在它們被繪制到實(shí)際的DOM之前才會(huì)被調(diào)用。
這意味著,如果我們確實(shí)需要對(duì)任何DOM元素進(jìn)行任何JavaScript查詢,useLayoutEffect是我們可能需要的鉤子。
鉤子流程
- 你以某種方式導(dǎo)致渲染(改變狀態(tài),或者父類重新渲染)。
- React渲染你的組件(調(diào)用它)
- useLayoutEffect運(yùn)行,React等待它完成。
- 屏幕在視覺上被更新
什么時(shí)候使用useLayoutEffect鉤子?
在使用useEffect鉤子時(shí),有一個(gè)常見的問題,即當(dāng)一個(gè)組件的狀態(tài)被更新時(shí),它可能會(huì) "閃動(dòng)"。這是因?yàn)榻M件在繼續(xù)進(jìn)行異步計(jì)算的過(guò)程中,首先會(huì)以部分就緒的狀態(tài)進(jìn)行渲染,然后才會(huì)以最終的狀態(tài)進(jìn)行重新渲染。
這是一個(gè)很好的指示,你可能想使用useLayoutEffect鉤子來(lái)代替。
這樣的例子是試圖在點(diǎn)擊一個(gè)按鈕時(shí)生成并渲染一個(gè)極高的數(shù)值,就像這個(gè)例子中一樣:
import { useState, useEffect } from 'react'; import './App.css'; function App() { const [value, setValue] = useState(0); useEffect(() => { if (value === 0) { setValue(10 + Math.random() * 200); } }, [value]); console.log('render', value); return ( <div className="App"> <p>Value: {value}</p> <button onClick={() => setValue(0)}> Generate Random Value </button> </div> ); } export default App;
如果我們要檢查我們的應(yīng)用程序是如何表現(xiàn)的,我們將看到每次我們按下按鈕時(shí)一個(gè)不斷變化的閃爍的數(shù)字。
狀態(tài)更新時(shí)閃爍的組件
如果我們使用useLayoutEffect鉤子,我們就可以擺脫這個(gè)視覺錯(cuò)誤。
import { useState, useLayoutEffect } from 'react'; import './App.css'; function App() { const [value, setValue] = useState(0); useLayoutEffect(() => { if (value === 0) { setValue(10 + Math.random() * 200); } }, [value]); console.log('render', value); return ( <div className="App"> <p>Value: {value}</p> <button onClick={() => setValue(0)}> Generate Random Value </button> </div> ); } export default App;
而且,你可以從最后一個(gè)視頻樣本中看到,我們已經(jīng)能夠擺脫閃爍的效果了。
這是因?yàn)檫@兩個(gè)鉤子的行為略有不同;第一個(gè)鉤子是異步處理計(jì)算和DOM渲染的,而后者是先進(jìn)行計(jì)算,然后才處理計(jì)算結(jié)果在屏幕上的渲染。
在我們的例子中,這意味著useEffect鉤子正試圖生成隨機(jī)值,并同時(shí)將其渲染到屏幕上。另一方面,useLayoutEffect鉤子試圖首先完成計(jì)算,然后才向我們展示生成的數(shù)字。
總結(jié)
正如你所注意到的,useLayoutEffect鉤子為我們提供了一個(gè)干凈的解決方案,以解決我們可能發(fā)現(xiàn)自己經(jīng)常與之斗爭(zhēng)的問題,那就是被React同時(shí)處理DOM繪制和計(jì)算的方式所糾纏。
作為一個(gè)啟示,當(dāng)你在處理 ref 值或需要做任何類型的工作,圍繞著通過(guò)vanilla JavaScript方法(如querySelector、querySelectorAll或任何其他方式)查詢DOM元素時(shí),你可能想使用useLayoutEffect鉤。
請(qǐng)記住,盡管useLayoutEffect鉤子為我們提供了很多有用的東西,但在99%的情況下,你最好還是使用useEffect鉤子,因?yàn)樗捎谄洚惒降男再|(zhì),常常會(huì)有更高的性能。
所以,就這樣了。
希望你現(xiàn)在已經(jīng)對(duì)這兩個(gè)鉤子的用法有了更好的理解,以及每個(gè)鉤子可能派上用場(chǎng)的場(chǎng)景;這也是特別常見的,因?yàn)樗皇褂玫孟喈?dāng)少,要么是由于開發(fā)者不知道它,要么是知道它,但不確定它的具體作用。
以上就是React中useLayoutEffect鉤子使用場(chǎng)景詳解的詳細(xì)內(nèi)容,更多關(guān)于React useLayoutEffect鉤子的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
react中axios結(jié)合后端實(shí)現(xiàn)GET和POST請(qǐng)求方式
這篇文章主要介紹了react中axios結(jié)合后端實(shí)現(xiàn)GET和POST請(qǐng)求方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-02-02react 移動(dòng)端實(shí)現(xiàn)列表左滑刪除的示例代碼
這篇文章主要介紹了react 移動(dòng)端實(shí)現(xiàn)列表左滑刪除的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07解決React報(bào)錯(cuò)No duplicate props allowed
這篇文章主要為大家介紹了React報(bào)錯(cuò)No duplicate props allowed解決方法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12vite+react+tailwindcss的簡(jiǎn)單使用方式
這篇文章主要介紹了vite+react+tailwindcss的簡(jiǎn)單使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-01-01React自定義視頻全屏按鈕實(shí)現(xiàn)全屏功能
這篇文章主要介紹了React自定義視頻全屏按鈕實(shí)現(xiàn)全屏功能,通過(guò)繪制全屏按鈕,并綁定點(diǎn)擊事件,編寫點(diǎn)擊事件,通過(guò)實(shí)例代碼給大家詳細(xì)講解,需要的朋友可以參考下2022-11-11Reactjs?錯(cuò)誤邊界優(yōu)雅處理方法demo
這篇文章主要為大家介紹了Reactjs?錯(cuò)誤邊界優(yōu)雅處理方法demo,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12詳解React?如何防止?XSS?攻擊論$$typeof?的作用
這篇文章主要介紹了詳解React?如何防止?XSS?攻擊論$$typeof?的作用,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-07-07用react實(shí)現(xiàn)一個(gè)簡(jiǎn)單的scrollView組件
這篇文章主要給大家介紹一下如何用 react 實(shí)現(xiàn)一個(gè)簡(jiǎn)單的 scrollView組件,文中有詳細(xì)的代碼示例,具有一定的參考價(jià)值,需要的朋友可以參考下2023-07-07React?Native?加載H5頁(yè)面的實(shí)現(xiàn)方法
這篇文章主要介紹了React?Native?加載H5頁(yè)面的實(shí)現(xiàn)方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-04-04