React-useImperativeHandle (forwardRef)

我們會遇到這樣的場景:某個組件想要暴露一些方法,來供外部組件來調用。例如我們在開發form表單的時候,就需要把設置表單值、重置值、提交等方法暴露給外部使用。會有如下代碼:

import { forwardRef } from 'react';const Form = forwardRef(function MyForm(props, ref) {useImperativeHandle(ref, () => {return {// ... 你的方法 ...};}, []);return (<div {...props} ref={ref}><input type="text" /></div>);
});

在組件外部,只需傳入ref屬性,即可調用form組件提供的方法。

獲取最新的state

由于react中,setState之后,是采用異步調度、批量更新的策略,導致我們無法直接獲取最新的state。在使用class組件的時候,我們可以通過傳遞第二個參數,傳一個回調用函數,來讓我們獲取最新的state (在React 18以后,就算在class component里面,在setTimeout、原生事件回調里面,也是異步批量更新了)。在hooks里面,我目前只能通過useEffect,把當前state當作依賴傳入,來在useEffect回調函數里面獲取最新的state。
在setState的時候,其實就是在調用dispatchSetState,源碼如下 (刪掉了一些注釋和DEV代碼):

function dispatchSetState<S, A>(fiber: Fiber,queue: UpdateQueue<S, A>,action: A,
) // 計算更新優先級const lane = requestUpdateLane(fiber);const update: Update<S, A> = {lane,action,hasEagerState: false,eagerState: null,next: (null: any),};// 判斷當前fiber是否正在處于更新中,若是則把當前更新進行排隊if (isRenderPhaseUpdate(fiber)) {enqueueRenderPhaseUpdate(queue, update);} else {const alternate = fiber.alternate;if (fiber.lanes === NoLanes &&(alternate === null || alternate.lanes === NoLanes)) {const lastRenderedReducer = queue.lastRenderedReducer;if (lastRenderedReducer !== null) {let prevDispatcher;try {const currentState: S = (queue.lastRenderedState: any);const eagerState = lastRenderedReducer(currentState, action);update.hasEagerState = true;update.eagerState = eagerState;// 若新舊狀態無變化,則直接返回,啥也不干if (is(eagerState, currentState)) {enqueueConcurrentHookUpdateAndEagerlyBailout(fiber, queue, update);return;}} catch (error) {// Suppress the error. It will throw again in the render phase.} finally {if (__DEV__) {ReactCurrentDispatcher.current = prevDispatcher;}}}}const root = enqueueConcurrentHookUpdate(fiber, queue, update, lane);if (root !== null) {const eventTime = requestEventTime();scheduleUpdateOnFiber(root, fiber, lane, eventTime);entangleTransitionUpdate(root, queue, lane);}}markUpdateInDevTools(fiber, lane, action);
}

scheduleUpdateOnFiber則是react內部的核心調度方法,源碼如下:

export function scheduleUpdateOnFiber(root: FiberRoot,fiber: Fiber,lane: Lane,eventTime: number,
) {checkForNestedUpdates();// Mark that the root has a pending update.markRootUpdated(root, lane, eventTime);if ((executionContext & RenderContext) !== NoLanes &&root === workInProgressRoot) {warnAboutRenderPhaseUpdatesInDEV(fiber);// Track lanes that were updated during the render phaseworkInProgressRootRenderPhaseUpdatedLanes = mergeLanes(workInProgressRootRenderPhaseUpdatedLanes,lane,);} else {// This is a normal update, scheduled from outside the render phase. For// example, during an input event.if (enableUpdaterTracking) {if (isDevToolsPresent) {addFiberToLanesMap(root, fiber, lane);}}warnIfUpdatesNotWrappedWithActDEV(fiber);if (enableProfilerTimer && enableProfilerNestedUpdateScheduledHook) {if ((executionContext & CommitContext) !== NoContext &&root === rootCommittingMutationOrLayoutEffects) {if (fiber.mode & ProfileMode) {let current = fiber;while (current !== null) {if (current.tag === Profiler) {const {id, onNestedUpdateScheduled} = current.memoizedProps;if (typeof onNestedUpdateScheduled === 'function') {onNestedUpdateScheduled(id);}}current = current.return;}}}}if (enableTransitionTracing) {const transition = ReactCurrentBatchConfig.transition;if (transition !== null) {if (transition.startTime === -1) {transition.startTime = now();}addTransitionToLanesMap(root, transition, lane);}}if (root === workInProgressRoot) {if (deferRenderPhaseUpdateToNextBatch ||(executionContext & RenderContext) === NoContext) {workInProgressRootInterleavedUpdatedLanes = mergeLanes(workInProgressRootInterleavedUpdatedLanes,lane,);}if (workInProgressRootExitStatus === RootSuspendedWithDelay) {markRootSuspended(root, workInProgressRootRenderLanes);}}ensureRootIsScheduled(root, eventTime);if (lane === SyncLane &&executionContext === NoContext &&(fiber.mode & ConcurrentMode) === NoMode &&// Treat `act` as if it's inside `batchedUpdates`, even in legacy mode.!(__DEV__ && ReactCurrentActQueue.isBatchingLegacy)) {resetRenderTimer();flushSyncCallbacksOnlyInLegacyMode();}}
}

我們繼續追蹤ensureRootIsScheduled方法,此源碼就省略了,然后會調用scheduleMicrotask方法,源碼如下:


export const scheduleMicrotask: any =typeof queueMicrotask === 'function'? queueMicrotask: typeof localPromise !== 'undefined'? callback =>localPromise.resolve(null).then(callback).catch(handleErrorInNextTick): scheduleTimeout;

會優先使用queueMicrotask來添加一個微任務,此方法是一個標準的web api,可以不借助Promise來往微任務隊列里面添加一個任務。若當前環境不支持queueMicrotask,則依次優先使用Promise,setTimeout。這與vue的nextTick源碼實現是基本一致的。通過以上的分析,我們可以大致了解了react異步批量更新的調度過程。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/77575.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/77575.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/77575.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

多人五子棋聯機對戰平臺 測試報告

目錄 項目介紹 測試用例設計 部分功能測試示例 自動化測試 測試范圍 排除范圍 自動化測試目錄?編輯 執行全部自動化測試用例 性能說明 總結 性能測試 結果分析 測試總結 項目介紹 該項目基于WebSocket實現實時通信&#xff0c;采用SSM框架構建在線五子棋多人聯機…

JAVAEE(網絡原理—UDP報頭結構)

我們本篇文章要講的是UDP的報頭結構以及注意事項。 下面呢&#xff0c;我先說一下UDP是什么&#xff1f; 1.UDP是什么&#xff1f; UDP是一種網絡協議。網絡協議是計算機網絡中&#xff0c;為了使不同設備之間能夠準確、高效地進行數據交換和通信&#xff0c;而預先制定的一…

STM32學習筆記匯總

所有學習資料均參考b站江科大&#xff0c;和鐵山羊 一.創建工程&#xff08;比較麻煩&#xff0c;而且時間長了就容易忘記&#xff09; 二.點燈大師&#xff08;成功的第一步&#xff09; 三.不同的燒錄器使用&#xff08;Jlink-stlink&#xff09;

【MySQL】SQL語句在MySQL中的執行過程?主要存儲引擎區別?

MySQL SQL語句執行過程詳解 作為面試官&#xff0c;我來詳細剖析一條SQL語句在MySQL中的完整執行過程&#xff0c;這是每個后端開發者都應該掌握的核心知識。 一、連接階段 建立連接 客戶端通過TCP/IP協議與MySQL服務器建立連接(默認3306端口)服務器驗證用戶名、密碼和權限…

【記錄】服務器安裝ffmpeg

前言 因為項目中需要用到 ffmpeg 進行圖像的一些操作,本文記錄下在服務器安裝 ffmpeg 的全過程,還是具有一定挑戰性的。 系統詳情 本文使用的操作系統詳情如下 通過 命令 cat /etc/os-release 獲取 雖然操作系統為 Rocky Linux,但安裝過程是通用的,因為本文記錄的是從源代碼…

Django之modelform使用

Django新增修改數據功能優化 目錄 1.新增數據功能優化 2.修改數據功能優化 在我們做數據優化處理之前, 我們先回顧下傳統的寫法, 是如何實現增加修改的。 我們需要在templates里面新建前端的頁面, 需要有新增還要刪除, 比如說員工數據的新增, 那需要有很多個輸入框, 那html…

HTML5 應用程序緩存:原理、實踐與演進

在 Web 技術的發展歷程中&#xff0c;HTML5 引入的應用程序緩存&#xff08;Application Cache&#xff09;曾是提升 Web 應用離線體驗的重要技術。它允許 Web 應用進行緩存&#xff0c;使用戶在沒有因特網連接時也能訪問應用&#xff0c;為 Web 應用帶來了顯著的優勢。然而&am…

【問題筆記】解決python虛擬環境運行腳本無法激活問題

【問題筆記】解決python虛擬環境運行腳本無法激活問題 錯誤提示問題所在解決方法**方法 1&#xff1a;臨時更改執行策略****方法 2&#xff1a;永久更改執行策略** **完整流程示例** 錯誤提示 PS F:\PythonProject\0419graphrag-local-ollama-main> venv1\Scripts\activate…

解決echarts餅圖label顯示不全的問題

解決辦法 添加如下配置&#xff1a; labelLayout: {hideOverlap: false},

Pandas數據合并與重塑

在數據處理與分析的領域中&#xff0c;Pandas 無疑是一顆璀璨的明星。它提供了豐富且強大的功能&#xff0c;讓我們能夠輕松應對各種復雜的數據操作。其中&#xff0c;數據合并與重塑是兩個至關重要的環節&#xff0c;它們能夠幫助我們整合不同來源的數據&#xff0c;調整數據的…

Nodejs數據庫單一連接模式和連接池模式的概述及寫法

概述 單一連接模式和連接池模式是數據庫連接的兩種主要方式&#xff1a; 單一連接模式&#xff1a; 優點&#xff1a;實現簡單&#xff0c;適合小型應用缺點&#xff1a;每次請求都需要創建新連接&#xff0c;連接創建和銷毀開銷大&#xff0c;并發性能差&#xff0c;容易出…

將 DeepSeek 集成到 Spring Boot 項目實現通過 AI 對話方式操作后臺數據

文章目錄 項目簡介GiteeMCP 簡介環境要求項目代碼核心實現代碼MCP 服務端&#xff08;批量注冊 Tool&#xff09;MCP 客戶端&#xff08;調用 DeepSeek&#xff09; DeepSeek APIDockersse 連接ws 連接&#xff08;推薦&#xff09;http 連接 Cherry Studio配置模型配置 MCP調用…

【HDFS入門】HDFS性能調優實戰:壓縮與編碼技術深度解析

目錄 1 HDFS性能調優概述 2 HDFS壓縮技術原理與應用 2.1 常見壓縮算法比較 2.2 壓縮流程架構 2.3 壓縮配置實踐 3 列式存儲編碼技術 3.1 ORC與Parquet對比 3.2 ORC文件結構 3.3 Parquet編碼流程 4 性能調優實戰建議 4.1 壓縮選擇策略 4.2 編碼優化技巧 5 性能測試…

HCIP --- OSPF綜合實驗

一、拓撲圖 二、實驗要求 1&#xff0c;R5為ISP&#xff0c;其上只能配置IP地址;R4作為企業邊界路由器&#xff0c;出口公網地址需要通過PPP協議獲取&#xff0c;并進行chap認證。 2&#xff0c;整個0SPF環境IP基于172.16.0.8/16劃分。 3&#xff0c;所有設備均可訪問R5的環…

c++:線程(std::thread)

目錄 從第一性原理出發&#xff1a;為什么需要線程&#xff1f; ? 本質定義&#xff1a; &#x1f4cc; 使用基本語法&#xff1a; 線程之間的“并發”與“并行”的區別 線程安全與數據競爭&#xff08;Race Condition&#xff09; 如何讓線程“安全地”訪問數據&#x…

PCL軟件架構

Point Cloud Library (PCL) 采用模塊化設計,提供了豐富的點云處理功能。以下是PCL的核心架構和主要類的詳細介紹。 一、PCL整體架構 PCL的架構可以分為以下幾個主要層次: 數據表示層:基礎點云數據結構和基本操作 算法層:各種點云處理算法實現 I/O層:點云數據的輸入輸出 …

CCLinkIE轉EtherCAT邊緣計算網關構建智能產線:跨協議設備動態組網與數據優化傳輸

一、行業背景 隨著新能源汽車市場爆發式增長&#xff0c;汽車制造企業對產線效率、設備協同性及柔性生產能力的要求顯著提升。傳統產線多采用CC-LinkIEFieldBasic&#xff08;CCLINKIEFB&#xff09;協議的三菱PLC控制系統&#xff0c;而新一代伺服驅動設備普遍采用EtherCAT協…

模態雙俠闖江湖:SimTier 分層破局,MAKE 智煉新知

目錄 利用多模態表示提升淘寶展示廣告效果&#xff1a;挑戰、方法與洞察摘要1 引言2 預備知識推薦模型中的ID特征基于ID的模型結構 3 多模態表示的預訓練3.1 語義感知對比學習3.2 預訓練數據集的構建3.3 優化 4 與推薦模型的集成4.1 觀察和見解4.2 方法一&#xff1a;SimTier4.…

基于大模型的下肢靜脈曲張全流程預測與診療方案研究報告

目錄 一、引言 1.1 研究背景與意義 1.2 研究目的與創新點 1.3 研究方法與數據來源 二、下肢靜脈曲張概述 2.1 定義與病理生理 2.2 風險因素與臨床表現 2.3 診斷方法與現有治療手段 三、大模型預測原理與構建 3.1 大模型技術簡介 3.2 預測模型的數據收集與預處理 3.…

跨站腳本(XSS) 的詳細分類、對比及解決方案

以下是 跨站腳本&#xff08;XSS&#xff09; 的詳細分類、對比及解決方案&#xff1a; 一、XSS的分類與詳解 1. 反射型XSS&#xff08;非持久型XSS&#xff09; 定義&#xff1a;攻擊載荷通過URL參數傳遞&#xff0c;服務器直接返回到頁面中&#xff0c;需用戶主動觸發。 工…