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