返回顶部
首页 > 资讯 > 前端开发 > JavaScript >一文搞懂 React 18 中的 useTransition() 与 useDeferredValue()
  • 230
分享到

一文搞懂 React 18 中的 useTransition() 与 useDeferredValue()

2024-04-02 19:04:59 230人浏览 泡泡鱼
摘要

目录前言什么是Concurrent React?设置项目实现 useTransition()isPending 是做什么的?前言 React 18 引入了一个关键的新概念,称为&ld

前言

React 18 引入了一个关键的新概念,称为“Concurrent”。

并发涉及同时执行多个状态更新,这可以说是 React 18 中最重要的特性。除了并发之外,React 18 还引入了两个新的钩子,称为 useTransition() 和 useDeferredValue() 钩子。

它们都有助于降低状态更新的优先级,但问题是,何时应该使用它们?

什么是Concurrent React?

根据官方 React18 Docs,并发 React 是:

一种新的幕后机制,使 React 能够同时准备多个版本的 UI。您可以将并发视为一个实现细节——它的价值在于它的特性。

并发可以定义为同时执行大量任务的能力。并发并不是一个特性。相反,它是一个幕后功能,它允许 React 同时(并发地)准备许多 UI 实例。 React 以一种对开发人员隐藏实现细节的方式创建 api。 React 创建者认为,React 开发人员应该专注于 React 功能将如何帮助他们实现他们希望为客户提供的用户体验,并且 React 将弄清楚如何提供这种体验。

Concurrent React 不仅仅是一个实现细节。相反,它是更新框架核心渲染架构的重大升级。因此,了解它在 React 18 中是如何工作的至关重要。

设置项目

对于本文,我创建了一个 GitHub 存储库,在其中我构建了一个简单的演示产品应用程序,允许用户通过输入产品编号来查看产品。首先,您必须克隆包含所有项目启动文件的 github 存储库。要克隆 Github 存储库,请转到终端并运行以下命令:

git clone https://github.com/geekskai/react18-feature.git

完成克隆过程后,转到项目文件夹,在代码编辑器上打开它,转到编辑器终端,然后通过运行npm install 或安装脚本和依赖项 yarn install然后,要启动项目,请执行 npm start

应用程序启动后,它应该如下所示:

实现 useTransition()

当您第一次输入产品编号以获取product时,您会注意到它几乎会立即更新,即使它是一个包含 10,000 项要浏览的超长列表。

现在,当您转到 Chrome 浏览器的开发人员工具部分,转到性能选项卡,打开 CPU 节流并将 CPU 速度降低 4 倍时,问题就开始了。

如果您现在在降低 CPU 速度后尝试输入产品编号,您会注意到更新变得更慢且卡顿明显。甚至整个界面看起来和感觉都很迟钝,尤其是输入字段,现在在我们输入和删除时感觉没有响应。 而这绝对不是一个好的用户体验。

你看不到我在打字,但界面响应很慢,如上所示。甚至在 React18 之前,一个标准的解决方案不是一次处理 10,000 个项目或产品(在我们的例子中)。您可以使用分页或任何其他技术,或者在服务器端而不是客户端进行过滤。这些都是您在遇到此类问题时可以考虑的所有可能的解决方案。

但是,如果您需要在客户端执行这种操作,即在您的客户端代码上,那么使用 React18,您现在拥有一些工具,可以通过延迟一些状态更新操作来为用户提供更好的感知性能通过告诉 React 一些更新操作比其他操作具有更高的优先级。这就是 React 18 引入的并发以及相关的钩子和函数背后的想法。

useTransition() 告诉 React 一些状态更新具有较低的优先级,即每个其他状态更新或 UI 渲染触发器具有较高的优先级。当我们调用 useTransition() 时,我们得到一个包含两个元素的数组:一个 isPending 布尔值,它指示低优先级状态更新是否仍处于挂起状态,以及一个 startTransition() 函数,您可以将状态更新包装起来告诉 React这是一个低优先级的更新。

查看如何使用 useTransition() 钩子。首先,转到 App.js 文件并编辑代码,如下所示:

function App() {
  const [isPending, startTransition] = useTransition();
  const [filterTerm, setFilterTerm] = useState('');
  
  const filteredProducts = filterProducts(filterTerm);
  
  function updateFilterHandler(event) {
    startTransition(() => {
      setFilterTerm(event.target.value);
    });
  }
 
  return (
    <div id="app">
      <input type="text" onChange={updateFilterHandler} />
      <ProductList products={filteredProducts} />
    </div>
  );
}

因为 startTransition() 包装了 setFilterTerm() 状态更新函数,所以 React 给这个状态更新代码一个较低的优先级。这可确保输入字段保持响应并立即响应演示应用程序中的击键。如果未使用 useTransition(),应用程序可能会变得无响应,尤其是在速度较慢的设备上。当您输入产品编号时,您会看到代码现在响应速度更快且延迟更少,即使 CPU 已减慢 4 倍。您可以在您的系统上尝试此操作并查看结果。

但是,您不应该开始使用 startTransition 来结束所有状态更新。仅当您的用户界面较慢时才使用它,尤其是在旧设备上,或者在您没有其他解决方案可使用的情况下。这是因为它占用了额外的性能。

isPending 是做什么的?

isPending 告诉您当前是否有一些状态更新仍处于待处理状态(React 尚未执行,并且优先级较低。您可以使用 isPending 更新 UI 以在等待主要状态时显示一些后备内容更新完成。

我们可以在 App.ts 文件中的以下代码中看到这一点:

return (
    <div id="app">
      <input type="text" onChange={updateFilterHandler} />
      {isPending && <p style={{color: 'white'}}>Updating list..</p>}
      <ProductList products={filteredProducts} />
    </div>
  );
}

实现代码后,您应该能够在运行应用程序时看到如下内容:

因此,这也是您在使用 useTransition() 时可以使用的功能。另外,请注意观察实现 useTransition() 功能后它的响应速度有多快。

到此这篇关于一文搞懂 React 18 中的 useTransition() 与 useDeferredValue()的文章就介绍到这了,更多相关React useDeferredValue内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: 一文搞懂 React 18 中的 useTransition() 与 useDeferredValue()

本文链接: https://lsjlt.com/news/167336.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 一文搞懂 React 18 中的 useTransition() 与 useDeferredValue()
    目录前言什么是Concurrent React?设置项目实现 useTransition()isPending 是做什么的?前言 React 18 引入了一个关键的新概念,称为&ld...
    99+
    2024-04-02
  • 一文搞懂redux在react中的初步用法
    Redux是一个数据状态管理插件,当使用React或是vue开发组件化的SPA程序时,组件之间共享信息是一个非常大的问题。例如,用户登陆之后客户端会存储用户信息(ID,头像等),而系...
    99+
    2024-04-02
  • 一文搞懂Spring中的JavaConfig
    目录配置类注册组件扫描包配置事务注解驱动单元测试加载配置类properties配置文件加载(了解)aspectj注解开关传统spring一般都是基于xml配置的,不过后来新增了许多J...
    99+
    2024-04-02
  • 一文搞懂Spring中的注解与反射
    目录前言一、内置(常用)注解1.1@Overrode1.2@RequestMapping1.3@RequestBody1.4@GetMapping1.5@PathVariable1....
    99+
    2024-04-02
  • 一文搞懂JavaScript中原型与原型链
    目录前言构造函数创建对象prototype__proto__constructor实例与原型原型链总结constructor_proto_前言 js中的原型与原型链应该是老生常谈的话...
    99+
    2024-04-02
  • 一文搞懂Python中函数的定义与使用
    目录函数的定义和调用无参函数有参函数带有返回值的函数函数与循环结合与while循环结合与for循环结合函数的分类内置函数自定义函数函数的嵌套调用函数的嵌套定义函数的定义和调用 函数的...
    99+
    2024-04-02
  • 一文搞懂C++中继承的概念与使用
    目录前言继承概念及定义继承概念继承定义继承方式父类和子类对象赋值转换继承中的作用域派生类的默认成员函数派生类的友元与静态成员继承关系单继承多继承菱形继承前言 我们都知道面向对象语言的...
    99+
    2024-04-02
  • 一文搞懂python中Tkinter的使用
    本篇文章给大家带来了关于Python的相关知识,其中主要整理了Tkinter的相关问题,Tkinter 是使用 python 进行窗口视窗设计的模块,下面一起来看一下,希望对大家有帮助。【相关推荐:Python3视频教程 】一、前言1.1、...
    99+
    2022-07-04
    python
  • 一文搞懂Java中的日期类
    目录一、日期类1.1 第一代日期类1.2 第二代日期类Calendar1.3 第三代日期类一、日期类 在程序的开发中我们经常会遇到日期类型的操作,Java对日期类型的操作提供了很好的...
    99+
    2024-04-02
  • 一文搞懂Go语言中文件的读写与创建
    目录1. 文件的打开与关闭1.1 os.open1.2 os.OpenFile() 指定模式打开文件2. 文件的读取2.1 打开文件的方式读取文件中的数据2.2 使用 bufio 整...
    99+
    2024-04-02
  • 一文搞懂Scrapy与MongoDB交互过程
    Pipeline.py class MongoDBPipeline: def __init__(self,conn,database): self.conn = conn self...
    99+
    2022-07-08
    Scrapy与MongoDB Scrapy与MongoDB交互
  • 一文带你搞懂Python中的pyc文件
    目录pyc 文件的触发pyc 文件的导入pyc 文件包含的内容pyc 文件的写入字节码混淆pyc 文件的触发 上一篇文章我们介绍了字节码,当时提到,py 文件在执行的时候会先被编译成...
    99+
    2022-12-28
    Python pyc文件写入 Python pyc文件 Python pyc
  • 一文搞懂Java中的序列化与反序列化
    目录序列化和反序列化的概念应用场景序列化实现的方式继承Serializable接口,普通序列化继承Externalizable接口,强制自定义序列化serialVersionUID的...
    99+
    2024-04-02
  • 一文搞懂Golang中的内存逃逸
    目录前言什么是内存逃逸查看对象是否发生逃逸内存逃逸分析的意义怎么避免内存逃逸小结前言 我们都知道go语言中内存管理工作都是由Go在底层完成的,这样我们可以不用过多的关注底层的内存问题...
    99+
    2024-04-02
  • 一文彻底搞懂Kotlin中的协程
    产生背景 为了解决异步线程产生的回调地狱 //传统回调方式 api.login(phone,psd).enquene(new Callback<User>(){ ...
    99+
    2024-04-02
  • 一文搞懂Spring中的Bean作用域
    目录概述Singletonprototyperequestsessionapplication概述 scope用来声明容器中的对象所应该处的限定场景或者说该对象的存活时间,即容器在对...
    99+
    2024-04-02
  • 一文搞懂JavaScript中的内存泄露
    目录什么是内存泄漏怎么检测内存泄漏PerformanceMemory内存泄漏的场景垃圾回收算法引用计数循环引用标记清除闭包是内存泄漏吗总结以前我们说的内存泄漏,通常发生在后端,但是不...
    99+
    2024-04-02
  • 一文搞懂Python中is和==的区别
    目录==比较操作符和is同一性运算符区别哪些情况下is和==结果是完全相同的?为什么256时相同, 而1000时不同?结论==比较操作符和is同一性运算符区别哪些情况下is和==结果...
    99+
    2023-01-10
    Python中is和==的区别 Python中is用法
  • 一文搞懂Java中的反射机制
    目录一. 反射的概念二. 为什么需要反射三. 反射的基石四. 反射的实现1. 获取字节码文件对象 2. 反射的使用 反射的优缺点 一. 反射的概念 Ja...
    99+
    2024-04-02
  • 一文带你搞懂Java中的递归
    目录概述递归累加求和计算1 ~ n的和代码执行图解递归求阶乘递归打印多级目录综合案例文件搜索文件过滤器优化Lambda优化概述 递归:指在当前方法内调用自己的这种现象。 递归的分类:...
    99+
    2022-11-13
    Java 递归
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作