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.mzph.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;将每个高频面试题可能进行延伸的题目再次进行排序选出高频延伸八股题。面试官都是以点破…