AVt天堂网 手机版,亚洲va久久久噜噜噜久久4399,天天综合亚洲色在线精品,亚洲一级Av无码毛片久久精品

當前位置:首頁 > 科技  > 軟件

一圖看懂 React 源碼中的同步更新邏輯

來源: 責編: 時間:2024-05-11 09:21:16 247觀看
導讀在 React 源碼中,scheduleUpdateOnFiber 是所有任務的唯一入口方法。我們前面分析 useState 的實現原理章節中,我們可以清晰的知道,當我們調用 dispatchSetState 時,最終會調用該入口方法。scheduleUpdateOnFiber 主要用

zhX28資訊網——每日最新資訊28at.com

在 React 源碼中,scheduleUpdateOnFiber 是所有任務的唯一入口方法。我們前面分析 useState 的實現原理章節中,我們可以清晰的知道,當我們調用 dispatchSetState 時,最終會調用該入口方法。zhX28資訊網——每日最新資訊28at.com

zhX28資訊網——每日最新資訊28at.com

scheduleUpdateOnFiber 主要用于觸發一個 Fiber 節點上的調度更新任務,該函數里主要有兩個核心邏輯。zhX28資訊網——每日最新資訊28at.com

// Mark that the root has a pending update.// 標記 root 上有一個更新任務markRootUpdated(root, lane, eventTime);ensureRootIsScheduled(root, eventTime);

markRootUpdated 的邏輯如下,簡單了解一下即可。zhX28資訊網——每日最新資訊28at.com

export function markRootUpdated(  root: FiberRoot,  updateLane: Lane,  eventTime: number,) {  // 設置本次更新的優先級  root.pendingLanes |= updateLane;  // 重置 root 應用根節點的優先級  if (updateLane !== IdleLane) {      // 由 Suspence 而掛起的 update 對應的 lane 集合    root.suspendedLanes = NoLanes;     // 由請求成功,Suspence 取消掛起的 update 對應的 Lane 集合    root.pingedLanes = NoLanes;   }  const eventTimes = root.eventTimes;  const index = laneToIndex(updateLane);  eventTimes[index] = eventTime;}

ensureRootIsScheduled 的主要目的要確保 root 根節點被調度。在該邏輯中,會根據 root.pendingLanes 信息計算出本次更新的 Lanes: nextLanes。zhX28資訊網——每日最新資訊28at.com

const nextLanes = getNextLanes(  root,  root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes,);

然后根據 nextLanes 計算出本批次集合中優先級最高的 Lane,作為本地任務的優先級。zhX28資訊網——每日最新資訊28at.com

// We use the highest priority lane to represent the priority of the callback.const newCallbackPriority = getHighestPriorityLane(nextLanes);

后續的邏輯就是取出當前已存在的調度優先級,與 newCallbackPriority 進行對比,根據對比結果來執行不同的更新方法。當該值等于 SyncLane 時,表示為同步更新。zhX28資訊網——每日最新資訊28at.com

同步優先級例如點擊事件。zhX28資訊網——每日最新資訊28at.com

然后會判斷是否支持微任務更新,如果不支持最后會執行 scheduleCallback。zhX28資訊網——每日最新資訊28at.com

if (newCallbackPriority === SyncLane) {  if (supportsMicrotasks) {    // Flush the queue in a microtask.    if (__DEV__ && ReactCurrentActQueue.current !== null) {      // Inside `act`, use our internal `act` queue so that these get flushed      // at the end of the current scope even when using the sync version      // of `act`.      ReactCurrentActQueue.current.push(flushSyncCallbacks);    } else {      scheduleMicrotask(() => {        // In Safari, appending an iframe forces microtasks to run.        // https://github.com/facebook/react/issues/22459        // We don't support running callbacks in the middle of render        // or commit so we need to check against that.        if (          (executionContext & (RenderContext | CommitContext)) ===          NoContext        ) {          // Note that this would still prematurely flush the callbacks          // if this happens outside render or commit phase (e.g. in an event).          flushSyncCallbacks();        }      });    }  } else {    // Flush the queue in an Immediate task.    scheduleCallback(ImmediateSchedulerPriority, flushSyncCallbacks);  }}

scheduleSyncCallback 的邏輯,也就是同步任務的調度非常簡單,就是將執行同步任務的回調添加到一個同步隊列 syncQueue 中。zhX28資訊網——每日最新資訊28at.com

export function scheduleSyncCallback(callback: SchedulerCallback) {  // Push this callback into an internal queue. We'll flush these either in  // the next tick, or earlier if something calls `flushSyncCallbackQueue`.  if (syncQueue === null) {    syncQueue = [callback];  } else {    // Push onto existing queue. Don't need to schedule a callback because    // we already scheduled one when we created the queue.    syncQueue.push(callback);  }}

這里的 callback 是之前傳入的 performSyncWorkOnRoot,這是用來執行同步更新任務的方法。他的邏輯主要包括:zhX28資訊網——每日最新資訊28at.com

  • 調用 renderRootSync,該方法會執行 workLoopSync,最后生成 Fiber true。
  • 將創建完成的 Fiber tree 掛載到 root 節點上。
  • 最后調用 commitRoot,進入 commit 階段修改真實 DOM。
function performSyncWorkOnRoot(root) {  ...  let exitStatus = renderRootSync(root, lanes);    ...  root.finishedWork = finishedWork;  root.finishedLanes = lanes;  commitRoot(    root,    workInProgressRootRecoverableErrors,    workInProgressTransitions,  );  ensureRootIsScheduled(root, now());  return null;}

workLoopSync 的邏輯也非常簡單,如下:zhX28資訊網——每日最新資訊28at.com

function workLoopSync() {  // Already timed out, so perform work without checking if we need to yield.  while (workInProgress !== null) {    performUnitOfWork(workInProgress);  }}

在 performUnitOfWork 中,會調用 beginWork 方法開始創建 Fiber 節點。zhX28資訊網——每日最新資訊28at.com

var next = beginWork(  current,   unitOfWork,   subtreeRenderLanes);

總結

同步更新的過程比較簡單,從 scheduleUpdateOnFiber 到 beginWork 這中間的流程里,大多數邏輯都在進行各種不同情況的判斷,因此源碼看上去比較吃力,實際邏輯并不是很重要,簡單了解即可,重要的是 beginWork 創建 Fiber 節點的方法,這跟我們之前文章里提到過的優化策略是一致的。zhX28資訊網——每日最新資訊28at.com

本文鏈接:http://www.tebozhan.com/showinfo-26-87990-0.html一圖看懂 React 源碼中的同步更新邏輯

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 一篇學會Go中reflect反射的詳細用法

下一篇: SpringBoot3使用虛擬線程一定要小心了

標簽:
  • 熱門焦點
Top