您好,登錄后才能下訂單哦!
這篇文章主要介紹了React中State的原理分析,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
如果對 React 底層有一定了解,可以回答出 batchUpdate 批量更新概念,以及批量更新被打破的條件。
答案:有時是同步,有時是異步。
在 合成事件 和 生命周期函數 里是 異步 的在 原生事件 和 setTimeout、promise
里是 同步 的
造成setState
的異步并不是由內部的異步代碼引起的,在本身的執行過程中時同步的,但是合成事件和生命周期函數的調用順序在更新之前,導致在內部不能直接得到更新后的值,可以用第二個參數 callback 來獲取。
具體解釋:可參考setState的執行過程
setState(obj,callback)
第一個參數:當 obj 為一個對象,則為即將合并的 state ;如果 obj 是一個函數,那么當前組件的 state 和 props 將作為參數,返回值用于合并新的 state。
第二個參數 callback :callback 為一個函數,函數執行上下文中可以獲取當前 setState 更新后的最新 state 的值,可以作為依賴 state 變化的副作用函數,可以用來做一些基于 DOM 的操作。
一次事件中觸發一次如上 setState ,在 React 底層執行過程:
render 階段 render 函數執行 -> commit 階段真實 DOM 替換 -> setState 回調函數執行 callback
首先,setState 會產生當前更新的優先級(老版本用 expirationTime ,新版本用 lane )。接下來 React 會從 fiber Root 根部 fiber 向下調和子節點,調和階段將對比發生更新的地方,更新對比 expirationTime ,找到發生更新的組件,合并 state,然后觸發 render 函數,得到新的 UI 視圖層,完成 render 階段。接下來到 commit 階段,commit 階段,替換真實 DOM ,完成此次更新流程。此時仍然在 commit 階段,會執行 setState 中 callback 函數,到此為止完成了一次 setState 全過程。
本質:React 底層調用 Updater 對象上的 enqueueSetState 方法
enqueueSetState()
:創建一個update,放入當前 fiber對象 的待更新隊列中,最后開啟調度更新,進入更新流程。
React 的 batchUpdate 批量更新
目的:多次 setstate 會讓邏輯多停留在 js 運行層面,阻塞了瀏覽器繪制,因此需要批量更新
batchedEventUpdates ()
:
分析流程:
React 事件執行前通過 isBatchingEventUpdates=true 打開開關,開啟事件批量更新
當事件結束,通過 isBatchingEventUpdates=false 關閉開關
在 scheduleUpdateOnFiber 中根據這個開關來確定是否進行批量更新
1)異步環境下,繼續開啟批量更新模式:
異步操作里面的批量更新規則會被打破,因此提供了手動批量更新方法: unstable_batchedUpdates
2)提升更新優先級:
提供了方法: flushSync
,可以將回調函數中的更新任務,放在一個較高的優先級中優先執行
補充:flushSync 在同步條件下,會合并之前的 setState | useState
3)總結:React 同一級別更新優先級 關系是:
flushSync 中的 setState > 正常執行上下文中 setState > 異步 setTimeout ,Promise 中的 setState
const [ state , dispatch ] = useState(initData)
① state 目的提供給 UI ,作為渲染視圖的數據源
② dispatch 改變 state 的函數,可以理解為推動函數組件渲染的渲染函數
③ initData 初始值
initData的初始值
第一種情況是非函數,將作為 state 初始化的值
第二種情況是函數,函數的返回值作為 useState 初始化的值
dispatch的參數
第一種非函數情況,此時將作為新的值,賦予給 state,作為下一次渲染使用
第二種是函數的情況,如果 dispatch 的參數為一個函數,這里可以稱它為reducer,reducer 參數,是上一次返回最新的 state,返回值作為新的 state
監聽 state 變化
useEffect
:常可以把 state 作為 依賴項 傳入 useEffect 第二個參數 deps ,但是注意 useEffect 初始化會默認執行一次
dispatch
更新特點
與類組件一樣,但是當調用改變 state 的函數dispatch,在本次函數執行上下文中,是獲取不到最新的 state 值的
原因:函數組件更新就是函數的執行,在一次執行過程中,函數內部所有變量重新聲明,所以改變的 state 只有在下一次函數執行時才更新。
useState 原理在之后 Hooks 講解
問:類組件中的 setState
和函數組件中的 useState
有什么異同?
答:相同點:
原理:setState 和 useState 更新視圖,底層都調用了 scheduleUpdateOnFiber 方法,而且事件驅動情況下都有批量更新規則
語法:第一個參數都可以傳入函數
不同點:
在不是 pureComponent 組件模式下, setState 不會淺比較兩次 state 的值。只要調用 setState 就會執行更新。但是 useState 中 dispatchAction 會默認比較兩次state是否相同來更新組件
setState 有專門監聽 state 變化的回調函數 callback,可以獲取最新 state。但是 useState 只能通過 useEffect 來執行 state 變化引起的副作用
setState 在底層處理邏輯時將舊 state 進行合并處理,而 useState 是重新賦值
感謝你能夠認真閱讀完這篇文章,希望小編分享的“React中State的原理分析”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。