」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 狀態測試案例中的 ReactDOM.unstable_batchedUpdates。

狀態測試案例中的 ReactDOM.unstable_batchedUpdates。

發佈於2024-11-09
瀏覽:351

在本文中,我們將研究 ReactDOM.unstable_batchedUpdates 在測試案例中的使用,特別是在 Zustand(React 的流行狀態管理庫)中。我們還將分解測試並解釋批次更新如何透過最小化不必要的重新渲染來增強 React 的效能。

理解測試案例

這是我們將要檢查的測試案例:

ReactDOM.unstable_batchedUpdates in Zustand’s testcase.

編寫此測試案例是為了驗證在將 Zustand 與 React 渲染系統一起使用時是否可以套用批次更新。

分解測試案例

1。 Zustand 商店設定: 第一步涉及使用建立功能建立 Zustand 商店:

const useBoundStore = create(
  (set) => ({   
  count: 0,   
  inc: () => set((state) => ({ count: state.count   1 })), }))

在這裡,儲存維護一個簡單的狀態,其中 count 屬性初始化為 0,並有一個 inc 函數來遞增計數。 set函數是Zustand更新狀態的方式,類似React中的setState。

2. Counter 元件: Counter 元件使用 useBoundStore 來擷取目前計數和 inc 函數:

const { count, inc } = useBoundStore()

此元件訂閱商店的狀態,對計數的任何變更都會導致其使用新值重新渲染。

3.使用 ReactDOM.unstable_batchedUpdates 提高效能: 在 useEffect 鉤子內部,inc 函式在 ReactDOM.unstable_batchedUpdates 區塊中被呼叫兩次:

useEffect(() => {   
  ReactDOM.unstable_batchedUpdates(() => {     
    inc()     
    inc()   
  }) 
}, [inc])

這就是奇蹟發生的地方。通常,每次呼叫 inc() 都會觸發單獨的更新,導致兩次渲染。然而,透過將這些呼叫包裝在unstable_batchedUpdates中,React能夠在一次更新中一起處理它們,從而只產生一次渲染。這透過減少渲染數量來優化效能,這在效能關鍵型應用程式中特別有用。

4。渲染元件並斷言結果 最後渲染元件,測試等待計數達到 2:

const { findByText } = render(
       
    >, 
)  

await findByText('count: 2')

此斷言確保在兩次增量後,計數正確更新並呈現為「count:2」。

什麼是 ReactDOM.unstable_batchedUpdates?

ReactDOM.unstable_batchedUpdates 是 React 提供的一種方法,允許在單一渲染週期中處理多個狀態更新。預設情況下,React 批次更新在事件處理程序(例如單擊事件)內觸發,這表示如果您更新多個狀態以響應用戶交互,React 將僅渲染組件一次。但是,在事件處理程序之外(例如在 setTimeout 或 useEffect 內),更新不會自動批次處理。

但在React 18之後這已經改變了。以下是從react.dev中挑選的螢幕截圖

ReactDOM.unstable_batchedUpdates in Zustand’s testcase.

ReactDOM.unstable_batchedUpdates in Zustand’s testcase.

請記住,文件顯示逾時、承諾、本機事件處理程序或任何其他事件內部的更新將以與 React 事件內部的更新相同的方式進行批次處理。但在 Zustand 的測試案例中,批次更新是在 useEffect` 內部應用的。這就是unstable_batchedUpdates 發揮作用的地方。它迫使 React 將多個狀態更新分組到單一渲染中,即使在事件驅動的上下文之外也是如此,從而最大限度地減少重新渲染並提高效能。

例子:

沒有unstable_batchedUpdates:

inc()  // triggers one render
inc()  // triggers another render

使用unstable_batchedUpdates:

ReactDOM.unstable_batchedUpdates(() => {
  inc()  // triggers only one render for both updates
  inc()
})

該方法被標記為“不穩定”,因為它不是 React 官方公共 API 的一部分,但它仍然在社群中廣泛用於效能最佳化。未來它可能會變得更加穩定或集成為 React 新的並發渲染功能的一部分。

有趣的事實:Zustand 的 4.5.5 版本使用版本 — 19.0.0-rc.0

ReactDOM.unstable_batchedUpdates in Zustand’s testcase.

為什麼在 Zustand 中使用 ReactDOM.unstable_batchedUpdates?

Zustand 是一個輕量級狀態管理函式庫,可與 React 的元件生命週期搭配使用。儘管 Zustand 可以有效地處理狀態更新,但 React 的反應系統將在每次狀態變更時觸發渲染。在短時間內發生多次狀態變化的場景下,使用ReactDOM.unstable_batchedUpdates可以防止多次重新渲染並大量更新,從而提供更流暢、更有效率的使用者體驗。

在提供的測試案例中,在批次更新中呼叫 inc 兩次可確保計數僅更新一次,從而比單獨運行每個更新更有效率。

關於我們:

在 Think Throo,我們的使命是教授開源專案中使用的高階程式碼庫架構概念。

透過在 Next.js/React 中練習高階架構概念,提升您的程式設計技能,學習最佳實踐並建立生產級專案。

我們是開源的 — https://github.com/thinkthroo/thinkthroo (請給我們一顆星!)

透過我們基於程式碼庫架構的高階課程來提升您的團隊技能。請透過 [email protected] 與我們聯繫以了解更多資訊!

參考:

  1. https://github.com/pmndrs/zustand/blob/v4.5.5/tests/basic.test.tsx#L175C7-L175C39

  2. https://dev.to/devmoustafa97/do-you-know-unstablebatchedupdates-in-react-enforce-batching-state-update-5cn2

  3. https://dev.to/jackbuchananconroy/react-18-what-s-changed-automatic-batching-13ec

  4. https://react.dev/blog/2022/03/08/react-18-upgrade-guide#automatic-batching

  5. https://github.com/pmndrs/zustand/blob/v4.5.5/package.json#L246C4-L247C32



版本聲明 本文轉載於:https://dev.to/thinkthroo/reactdomunstablebatchedupdates-in-zustands-testcase-4led?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>
  • 如何在 Go (Gorilla) 中向特定客戶端發送有針對性的 Websocket 更新?
    如何在 Go (Gorilla) 中向特定客戶端發送有針對性的 Websocket 更新?
    在Go (Gorilla) 中向特定客戶端發送Websocket 更新儘管是Go 新手,但您尋求有關實現Websocket 通信的指導您的預輸入項目。您已嘗試利用 Gorilla 的 GitHub 儲存庫中的範例,但在理解如何識別特定客戶端並針對 websocket 更新進行定位方面遇到了挑戰。 要...
    程式設計 發佈於2024-11-09
  • 大批
    大批
    方法是可以在物件上呼叫的 fns 數組是對象,因此它們在 JS 中也有方法。 slice(begin):將陣列的一部分提取到新數組中,而不改變原始數組。 let arr = ['a','b','c','d','e']; // Usecase: Extract till index ...
    程式設計 發佈於2024-11-09
  • 使用swoole作為基於ESP6的腳本可程式控制器的雲端物聯網閘道框架
    使用swoole作為基於ESP6的腳本可程式控制器的雲端物聯網閘道框架
    腳本可程式控制器的本機功能基本上已完成,開始實現遠端相關功能。 遠端系統整體架構如下: 使用ESP8266的SDK實作tcp伺服器和tcp客戶端。 在tcp伺服器的基礎上編寫http協議解析程式碼,設計簡單的http伺服器,處理與瀏覽器的資料交互,包括內建網頁的下載,並使用ajax技術獲取狀態並...
    程式設計 發佈於2024-11-09
  • Bootstrap 4 Beta 中的列偏移發生了什麼事?
    Bootstrap 4 Beta 中的列偏移發生了什麼事?
    Bootstrap 4 Beta:列偏移的刪除和恢復Bootstrap 4 在其Beta 1 版本中引入了重大更改柱子偏移了。然而,隨著 Beta 2 的後續發布,這些變化已經逆轉。 從 offset-md-* 到 ml-auto在 Bootstrap 4 Beta 1 中, offset-md-*...
    程式設計 發佈於2024-11-09
  • 為什麼在 Java 的 Random 類別中設定種子會傳回相同的數字?
    為什麼在 Java 的 Random 類別中設定種子會傳回相同的數字?
    Java隨機數產生:為什麼設定種子會回傳相同的數字? 儘管將Random類別的種子設定為特定值,但隨機數產生器始終會傳回相同的數字。讓我們探討一下可能導致此問題的原因。 了解 Random 類別和種子初始化Java Random 類別旨在產生偽隨機數。預設情況下,它使用其內部時鐘作為種子值,使其產生...
    程式設計 發佈於2024-11-09
  • 在 Go 中使用 WebSocket 進行即時通信
    在 Go 中使用 WebSocket 進行即時通信
    构建需要实时更新的应用程序(例如聊天应用程序、实时通知或协作工具)需要一种比传统 HTTP 更快、更具交互性的通信方法。这就是 WebSockets 发挥作用的地方!今天,我们将探讨如何在 Go 中使用 WebSocket,以便您可以向应用程序添加实时功能。 在这篇文章中,我们将介绍: WebSoc...
    程式設計 發佈於2024-11-09
  • 如何克服使用反射設定結構體欄位值時 SetCan() 總是傳回 False 的問題?
    如何克服使用反射設定結構體欄位值時 SetCan() 總是傳回 False 的問題?
    使用結構體的 SetString 探索反射反射提供了動態操作 Go 結構的強大工具。在此範例中,我們在嘗試使用反射來設定結構體欄位的值時遇到一個常見問題:CanSet() 始終傳回 false。這種障礙阻止了字段修改,使我們陷入困境。 識別陷阱提供的程式碼片段突顯了兩個基本錯誤:傳遞值而非指標: ...
    程式設計 發佈於2024-11-09
  • 為什麼 MySQL 中帶有子查詢的「IN」查詢很慢,如何提升效能?
    為什麼 MySQL 中帶有子查詢的「IN」查詢很慢,如何提升效能?
    MySQL 中帶有子查詢的緩慢「IN」查詢當使用子查詢時,使用「IN」運算子的MySQL查詢可能會表現出顯著的效能下降檢索「IN」子句的值很複雜。在這種情況下,用明確值取代子查詢結果會顯著縮短執行時間。 要了解此行為的原因,需要注意的是,每次評估「IN」查詢時,MySQL 都會執行子查詢。在提供的範...
    程式設計 發佈於2024-11-09
  • 如何使用WinAPI取得螢幕解析度?
    如何使用WinAPI取得螢幕解析度?
    使用 WinAPI 取得螢幕解析度在 WinAPI 中,存在多個函數來決定目前螢幕解析度。適當的選擇取決於具體要求。 檢索顯示尺寸檢索顯示尺寸檢索顯示尺寸 主監視器:使用GetSystemMetrics(SM_CXSCREEN) 和GetSystemMetrics( SM_CYCYSEN) 取得主顯...
    程式設計 發佈於2024-11-09
  • 如何修復透過 Gmail REST API 發送電子郵件時出現的「400 錯誤請求 + 失敗前提條件」錯誤?
    如何修復透過 Gmail REST API 發送電子郵件時出現的「400 錯誤請求 + 失敗前提條件」錯誤?
    Gmail REST API:解決“400 Bad Request Failed Precondition”錯誤嘗試使用Gmail REST API 與伺服器發送電子郵件時-到伺服器授權時,您可能會遇到一條錯誤訊息,指出「400 Bad Request Failed Precondition」。此錯...
    程式設計 發佈於2024-11-09
  • 如何使用 LOAD XML 和 XML_LOAD() 將缺少 ID 列的 XML 檔案匯入 MySQL?
    如何使用 LOAD XML 和 XML_LOAD() 將缺少 ID 列的 XML 檔案匯入 MySQL?
    使用XML_LOAD() 函數將XML 檔案匯入MySQL在這種情況下,您在嘗試使用下列命令將XML 檔案匯入MySQL 資料庫表時遇到錯誤載入XML 指令。出現此問題的原因是表中的欄位數與 XML 檔案中的值不匹配,且表中多了一個自動遞增 id 欄位。 要解決此錯誤,您可以指定要使用 LOAD X...
    程式設計 發佈於2024-11-09
  • C++ 物件的記憶體是如何組織的?
    C++ 物件的記憶體是如何組織的?
    C 物件的記憶體佈局動態轉換和重新解釋操作通常涉及操作物件記憶體指標。讓我們深入研究 C 如何在記憶體中組織對象,以便更好地理解這些操作。 根據 C 標準,類別或結構中非靜態資料成員的記憶體佈局主要由它們的宣告順序決定。具有相同存取說明符的成員按其聲明的順序排序。 除了成員變數之外,物件還為以下物件...
    程式設計 發佈於2024-11-09
  • 時間數據系列:故事的其餘部分
    時間數據系列:故事的其餘部分
    Time Data Series: The Rest of the Story - AdatoSystems It’s been a while since I wrote about PHP Zmanim – the work I’ve done with it and the ...
    程式設計 發佈於2024-11-09
  • 如何在 PyCharm 中輕鬆管理 Django 專案的環境變數?
    如何在 PyCharm 中輕鬆管理 Django 專案的環境變數?
    在PyCharm 中設定環境變數在處理依賴環境變數的專案時,擁有方便的方法直接在開發環境中管理這些設定至關重要。在本指南中,我們將示範如何在 PyCharm 中輕鬆設定環境變量,而無需求助於手動配置或 bash 檔案。 具體來說,我們將重點放在為Django 專案設定以下環境變數:DATABASE_...
    程式設計 發佈於2024-11-09
  • 如何修復 Windows 上的「pip install」存取被拒絕錯誤?
    如何修復 Windows 上的「pip install」存取被拒絕錯誤?
    克服Windows 上的「pip install」存取被拒絕錯誤使用pip 安裝可能是一項簡單的任務,但有時您可能會遇到存取錯誤在Windows 上出現拒絕錯誤,即使以管理員身分執行命令提示字元或PowerShell 也是如此。 此錯誤通常表現為:WindowsError: [Error 5] Ac...
    程式設計 發佈於2024-11-09

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3