React中useDeferredValue與useTransition終極對比。

文章目錄

  • 前言
    • 一、核心差異對比
    • 二、代碼示例對比
      • 1. `useDeferredValue`:延遲搜索結果更新
      • 2. `useTransition`:延遲路由切換
    • 三、應用場景總結
    • 四、注意事項
    • 五、原理剖析
        • 1. 核心機制對比
        • 2. 關鍵差異
        • 3. 代碼實現原理
  • 總結


前言

在React的并發模式下,useDeferredValueuseTransition是兩個強大的Hook,它們通過延遲非緊急的UI更新來提升用戶體驗,特別是在處理復雜渲染或高開銷任務時。本文將對比這兩個Hook的核心差異,并通過實際案例展示它們的典型應用場景。


一、核心差異對比

特性useDeferredValueuseTransition
核心作用延遲單個值的更新,標記為低優先級延遲一段邏輯的執行,標記為低優先級
返回值返回延遲后的值(deferredValue返回[isPending, startTransition]數組
觸發時機在組件更新時,優先使用舊值渲染,后臺再渲染新值通過startTransition包裹的邏輯會被標記為低優先級
適用場景高頻更新的輸入框、實時搜索、滾動列表等路由切換、復雜計算、非緊急狀態更新(如分頁加載)
性能影響減少頻繁渲染對主線程的阻塞,提升輸入流暢性避免關鍵任務被阻塞,保持UI響應性
與Suspense集成延遲更新不會觸發Suspense的fallback,保持舊版本顯示延遲邏輯不會觸發Suspense的fallback
底層機制基于并發渲染的優先級調度,動態調整延遲基于并發渲染的優先級調度,允許中斷低優先級任務

二、代碼示例對比

1. useDeferredValue:延遲搜索結果更新

	import { useState, useDeferredValue, useMemo } from 'react';import { Input, List } from 'antd';import mockjs from 'mockjs';interface Item {id: string;name: string;address: string;}export default function SearchPage() {const [inputValue, setInputValue] = useState('');const [list] = useState<Item[]>(() => {return mockjs.mock({'list|10000': [{'id|+1': 1,name: '@natural',address: '@county(true)',},],}).list;});const deferredQuery = useDeferredValue(inputValue);const isStale = deferredQuery !== inputValue;const filteredItems = useMemo(() => {return list.filter(item =>item.name.toString().includes(deferredQuery),);}, [deferredQuery, list]);return (<div><Inputvalue={inputValue}onChange={(e) => setInputValue(e.target.value)}placeholder="輸入搜索內容"/><Liststyle={{opacity: isStale ? '0.2' : '1',transition: 'all 1s',}}renderItem={(item) => (<List.Item><List.Item.Metatitle={item.name}description={item.address}/></List.Item>)}dataSource={filteredItems}/></div>);}

關鍵點

  • 輸入框的inputValue會立即更新,但deferredQuery會延遲更新。
  • 列表過濾僅在deferredQuery變化時觸發,避免頻繁渲染。
  • 當設備性能較好時,延遲幾乎無感知;當設備性能較差時,列表會在用戶停止輸入后更新。

2. useTransition:延遲路由切換

	import { useState, useTransition } from 'react';import { BrowserRouter as Router, Routes, Route, Link } from 'react-router-dom';function PageA() {return <div>Page A Content</div>;} function PageB() {return <div>Page B Content</div>;}function App() {const [currentPage, setCurrentPage] = useState('A');const [isPending, startTransition] = useTransition();const handleNavigation = (page) => {startTransition(() => {setCurrentPage(page);});};return (<Router><div><nav><Link to="/page-a" onClick={() => handleNavigation('A')}>Page A</Link><Link to="/page-b" onClick={() => handleNavigation('B')}>Page B</Link></nav>{isPending && <p>Loading...</p>}<Routes><Route path="/page-a" element={<PageA />} /><Route path="/page-b" element={<PageB />} /></Routes></div></Router>);}export default App;

關鍵點

  • 路由切換通過startTransition包裹,標記為低優先級任務。
  • isPending狀態顯示加載提示,避免用戶感到卡頓。
  • 高優先級任務(如用戶輸入)會優先執行,低優先級任務(如路由切換)會被延遲。

三、應用場景總結

場景推薦Hook原因
高頻更新的輸入框useDeferredValue延遲搜索結果更新,保持輸入流暢性,避免頻繁渲染。
實時搜索與過濾useDeferredValue延遲更新搜索結果列表,避免頻繁渲染導致卡頓,提升用戶體驗。
復雜數據渲染useDeferredValue延遲渲染大數據量列表或復雜組件樹,避免頻繁更新導致卡頓。
路由切換useTransition預加載下一頁數據時保持當前頁響應,避免用戶感到卡頓。
復雜計算任務useTransition延遲處理復雜計算任務,優先處理用戶交互,提升UI響應性。
非緊急狀態更新useTransition延遲更新非緊急狀態(如分頁加載),避免阻塞關鍵任務。

四、注意事項

  1. 避免濫用

    • 僅對用戶可感知的非緊急更新使用(如搜索建議、后臺數據加載)。
    • 避免對即時反饋的操作(如按鈕點擊、表單提交)使用,否則會延遲必要反饋,破壞用戶體驗。
  2. 狀態管理

    • startTransition中同時更新多個狀態時,React可能無法正確批處理。建議將多個狀態包裹在一個對象中處理,或使用useReducer管理復雜狀態。
  3. 副作用處理

    • 不要在startTransition中執行網絡請求、定時器等副作用。副作用應在useEffect或事件處理函數中執行。
  4. 與Suspense集成

    • 若在startTransition中觸發了Suspense回退(如懶加載組件),過渡期間會顯示fallback UI。可以通過isPending狀態自定義加載提示,避免重復加載效果沖突。
  5. 性能優化

    • 精準定位性能瓶頸,優先優化渲染邏輯,再考慮延遲更新。
    • 延遲值盡量為原始類型或穩定對象,避免不必要的后臺渲染。

五、原理剖析

1. 核心機制對比
  • useDeferredValue

    • 作用:延遲單個值的更新,將其標記為低優先級。
    • 原理:React 會優先使用舊值渲染,在后臺渲染新值。當高優先級任務(如用戶輸入)完成時,再更新為新值。
    • 底層:基于并發渲染的優先級調度,動態調整延遲。
  • useTransition

    • 作用:延遲一段邏輯的執行,將其標記為低優先級。
    • 原理:通過 startTransition 包裹的邏輯會被標記為低優先級,React 會優先處理高優先級任務(如用戶輸入),延遲處理低優先級任務。
    • 底層:基于并發渲染的優先級調度,允許中斷低優先級任務。
2. 關鍵差異
  • 觸發方式

    • useDeferredValue:延遲單個值的更新,返回延遲后的值。
    • useTransition:通過 startTransition 包裹邏輯,返回 [isPending, startTransition] 數組。
  • 適用場景

    • useDeferredValue:適用于高頻更新的輸入框、實時搜索、滾動列表等。
    • useTransition:適用于路由切換、復雜計算、非緊急狀態更新(如分頁加載)。
  • 性能影響

    • useDeferredValue:減少頻繁渲染對主線程的阻塞,提升輸入流暢性。
    • useTransition:避免關鍵任務被阻塞,保持 UI 響應性。
3. 代碼實現原理
  • useDeferredValue

    • React 在更新時,會首先嘗試使用舊值重新渲染,然后在后臺嘗試使用新值進行另一次渲染。
    • 如果組件未使用 React.memo,優化可能無效,因為子組件會頻繁重新渲染。
  • useTransition

    • startTransition 包裹的邏輯會被標記為低優先級,React 會優先處理高優先級任務。
    • isPending 狀態表示是否有待處理的低優先級任務。

總結

useDeferredValueuseTransition是React并發模式下優化渲染性能的重要工具。useDeferredValue適用于延遲單個值的更新,而useTransition適用于延遲一段邏輯的執行。通過合理使用這兩個Hook,可以顯著提升用戶體驗,特別是在處理高頻更新或復雜渲染任務時。然而,開發者必須小心處理并發渲染帶來的復雜性,確保應用的穩定性和可預測性。

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

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

相關文章

高并發內存池|定長內存池的設計

二、定長內存池的設計 設計一個定長的內存池&#xff0c;這個內存池的定長在于&#xff0c;當剩余空間使用完畢后&#xff0c;總是開辟相同長度的新空間來使用。我們會使用到一個指針來切割劃分大空間為小空間。大空間是內存池向系統申請的內存大小&#xff0c;而小空間是程序…

微信小程序 自定義圖片分享-繪制數據圖片以及信息文字

一 、需求 從數據庫中讀取頭像&#xff0c;姓名電話等信息&#xff0c;當分享給女朋友時&#xff0c;每個信息不一樣 二、實現方案 1、先將數據庫中需要的頭像姓名信息讀取出來加載到data 數據項中 data:{firstName:, // 姓名img:, // 頭像shareImage:,// 存儲臨時圖片 } 2…

從零開始理解Jetty:輕量級Java服務器的入門指南

目錄 一、Jetty是什么&#xff1f;先看一個生活比喻 二、5分鐘快速入門&#xff1a;搭建你的第一個Jetty服務 步驟1&#xff1a;Maven依賴配置 步驟2&#xff1a;編寫簡易Servlet&#xff08;廚房廚師&#xff09; 步驟3&#xff1a;組裝服務器&#xff08;餐廳開業準備&am…

深入淺出IIC協議 - 從總線原理到FPGA實戰開發 -- 第一篇:I2C總線協議深度解剖

第一篇&#xff1a;I2C總線協議深度解剖 副標題 : 兩根線如何征服千億設備&#xff1f;詳解硬件工程師必須掌握的通信奧義 1. 為什么I2C仍是嵌入式經典&#xff1f; 1.1 總線拓撲的哲學 拓撲對比圖 SPI需4線N片選 vs I2C僅2線級聯 UART點對點 vs I2C多主從架構 成本控制實…

MySQL 索引優化以及慢查詢優化

在數據庫性能優化中&#xff0c;索引優化和慢查詢優化是兩個關鍵環節。合理使用索引可以顯著提高查詢效率&#xff0c;而識別和優化慢查詢則能提升整體數據庫性能。本文將詳細介紹MySQL索引優化和慢查詢優化的方法和最佳實踐。 一、MySQL 索引優化 1.1 索引的基本概念 索引是…

vue使用Pinia實現不同頁面共享token

文章目錄 一、概述二、使用步驟安裝pinia在vue應用實例中使用pinia在src/stores/token.js中定義store在組件中使用store登錄成功后&#xff0c;將token保存pinia中向后端API發起請求時&#xff0c;攜帶從pinia中獲取的token 三、參考資料 一、概述 Pinia是Vue的專屬狀態管理庫…

通俗版解釋CPU、核心、進程、線程、協程的定義及關系

通俗版解釋&#xff08;比喻法&#xff09; 1. CPU 和核心 CPU 一個工廠&#xff08;負責干活的總部&#xff09;。核心 工廠里的車間&#xff08;比如工廠有4個車間&#xff0c;就能同時處理4個任務&#xff09;。 2. 進程 進程 一家獨立運營的公司&#xff08;比如一家…

用 VS Code / PyCharm 編寫你的第一個 Python 程序

用ChatGPT做軟件測試 編寫你的第一個 Python 程序——不只是“Hello, World”&#xff0c;而是構建認知、習慣與未來的起點 “第一行代碼&#xff0c;是一個開發者認知世界的方式。” 編程的入門&#xff0c;不只是運行一個字符串輸出&#xff0c;更是開始用計算機思維來理解、…

amd架構主機構建arm架構kkfileview

修改本機使用鏡像倉庫地址 vim /etc/docker/daemon.json {“experimental”: true, “registry-mirrors”: [ “https://docker.m.daocloud.io”, “https://docker.1panel.live”, “http://mirrors.ustc.edu.cn/”, “http://mirror.azure.cn/”, “https://docker.hpcloud.c…

[Linux] vim及gcc工具

目錄 一、vim 1.vim的模式 2.vim的命令集 (1):命令模式 (2):底行模式 3.vim配置 二、gcc 1.gcc格式及選項 2.工作布置 三、自動化構建工具makefile 1.基本使用方法 2.配置文件解析 3.拓展 在linux操作系統的常用工具中&#xff0c;常用vim來進行程序的編寫&#xff1b…

數據庫3——視圖及安全性

視圖及安全性 學習內容學習感受 學習內容 一、實驗目的與要求&#xff1a; 1、設計用戶子模式 2、根據實際需要創建用戶角色及用戶&#xff0c;并授權 3、針對不同級別的用戶定義不同的視圖&#xff0c;以保證系統的安全性 二、實驗內容&#xff1a; 1、 先創建四類用戶角色&…

Oracle數據庫如何進行冷備份和恢復

數據庫的冷備份指的是數據庫處于關閉或者MOUNT狀態下的備份&#xff0c;備份文件包括數據文件、日志文件和控制文件。數據庫冷備份所用的時間主要受數據庫大小和磁盤I/O性能的影響。由于數據庫需要關閉才能進行冷備份&#xff0c;所以這種備份技術并不適用724小時的系統。盡管冷…

SAP HCM 0008數據存儲邏輯

0008信息類型&#xff1a;0008信息類型是存儲員工基本薪酬的地方&#xff0c;因為很多企業都會都薪酬帶寬&#xff0c;都會按崗定薪&#xff0c;所以在上線前為體現工資體系的標準化&#xff0c;都會在配置對應的薪酬關系&#xff0c;HCM叫間接評估&#xff0c;今天我們就分析下…

FPGA在光譜相機中的核心作用

FPGA&#xff08;現場可編程門陣列&#xff09;作為光譜相機的核心控制與加速單元&#xff0c;通過硬件級并行處理能力和動態可編程特性&#xff0c;實現高速、高精度的光譜數據采集與處理。以下是其具體作用分類&#xff1a; 一、高速光電信號處理 ?實時光譜復原? 通過硬…

入門OpenTelemetry——部署OpenTelemetry

OpenTelemetry 部署模式 OpenTelemetry Collector 按部署方式分為 Agent 和Gateway 模式。 Agent 模式 在 Agent 模式下&#xff0c;OpenTelemetry 檢測的應用程序將數據發送到與應用程序一起駐留的&#xff08;收集器&#xff09;代理。然后&#xff0c;該代理程序將接管并…

Windows 上安裝下載并配置 Apache Maven

1. 下載 Maven 訪問官網&#xff1a; 打開 Apache Maven 下載頁面。 選擇版本&#xff1a; 下載最新的 Binary zip archive&#xff08;例如 apache-maven-3.9.9-bin.zip&#xff09;。 注意&#xff1a;不要下載 -src 版本&#xff08;那是源碼包&#xff09;。 2. 解壓 Mave…

摩方 12 代 N200 迷你主機(Ubuntu 系統)WiFi 抓包環境配置教程

摩方12代N200迷你主機標配 Intel AX201無線網卡&#xff0c;支持 WiFi 6 協議&#xff08;802.11ax&#xff09;及藍牙5.2。此網卡兼容主流抓包工具&#xff0c;但需注意&#xff1a; 驅動兼容性&#xff1a;Ubuntu 20.04及以上內核版本&#xff08;5.4&#xff09;默認支持AX2…

輕量、優雅、高擴展的事件驅動框架——Hibiscus-Signal

在現代企業級應用中&#xff0c;事件驅動架構&#xff08;EDA&#xff09;已成為解耦系統、提升擴展性的利器。今天給大家推薦一個非常優秀的國產輕量級事件驅動框架 —— Hibiscus Signal&#xff0c;它不僅天然整合 Spring Boot&#xff0c;還提供完整的事件生命周期支持&…

集合-進階

Collection collection的遍歷方式 迭代器遍歷 不依賴索引 import java.util.ArrayList; import java.util.Collection; import java.util.Iterator;public class mycollection {public static void main(String[] args) {//1.創建集合并添加元素Collection<String> co…

【八股戰神篇】Java集合高頻面試題

專欄簡介 八股戰神篇專欄是基于各平臺共上千篇面經&#xff0c;上萬道面試題&#xff0c;進行綜合排序提煉出排序前百的高頻面試題&#xff0c;并對這些高頻八股進行關聯分析&#xff0c;將每個高頻面試題可能進行延伸的題目再次進行排序選出高頻延伸八股題。面試官都是以點破…