【React】React 18 并发特性

React 18 引入了 并发特性(Concurrent Features),这是一次对 React 渲染机制的重大升级,让 React 更加智能、响应更流畅、资源更节省。

我们来详细讲解一下它的原理、特性、API 以及实际应用。


🧠 一、什么是并发特性(Concurrent Features)?

传统的 React 是 同步阻塞渲染:一旦开始渲染某个更新,就必须做完,不能中断,哪怕是非常耗时的任务,因此可能会发生阻塞。

之前,有时候加载一个复杂的图表,或者切换到一个内容很多的页面,整个页面就突然卡住,这就是 UI 卡顿或者说主线程阻塞。

React 18 引入的“并发特性”允许 React:

  • 中断当前的渲染任务,优先处理更紧急的更新(比如用户输入、动画)。
  • 将更新分片执行,避免阻塞主线程。
  • 自动调度优先级高的任务先执行,提高响应速度。
  • 支持 延迟加载(lazy loading)和流式渲染(Streaming)

这种机制称为 Concurrent Rendering(并发渲染),实现更智能的调度。

⚠️ 并不是你写的代码是“并发的”,而是 React 的内部调度机制变得更智能了。
⚠️ 并发不是并行,js 还是单线程,并发是任务调度策略。


🚀 二、如何启用并发特性?

从 React 18 开始,默认就支持并发功能,但 必须使用新的 createRoot API 才能激活。

// React 17 旧写法(不会启用并发特性)
ReactDOM.render(<App />, document.getElementById('root'));// React 18 新写法(启用并发特性)
import { createRoot } from 'react-dom/client';const root = createRoot(document.getElementById('root'));
root.render(<App />);

🔧 三、React 18 中的关键并发特性 API

1. startTransition()

用于把非紧急的更新(如筛选、排序、搜索)标记为 可中断任务

import { startTransition, useState } from 'react';function App() {const [input, setInput] = useState('');const [list, setList] = useState([]);function handleChange(e) {const value = e.target.value;setInput(value);// 标记为“过渡更新” => 可中断startTransition(() => {const filtered = hugeDataList.filter(item =>item.includes(value));setList(filtered);});}return (<><input value={input} onChange={handleChange} /><ul>{list.map(item => <li key={item}>{item}</li>)}</ul></>);
}

如果用户继续输入,React 会 中断上一个过滤渲染,执行最新的更新


2. useTransition()

useTransition 标记“不那么紧急”的更新。

允许将状态更新标记为“过渡(Transition)”, 降低其优先级。返回isPending
(布尔值,指示过渡是否待处理)和startTransition(函数,用于包裹低优先级状态更新)。

核心:控制状态更新的“时机”或“优先级”,避免阻塞高优先级交互。

更细粒度的过渡控制,可用于显示“加载中”状态:

const [isPending, startTransition] = useTransition();startTransition(() => {// 更新 state
});
{isPending ? '加载中...' : '加载完成'}

在这里插入图片描述


3. Suspense(改进支持)

React 18 支持在客户端和服务端都使用 Suspense 进行延迟加载。

import { Suspense, lazy } from 'react';const HeavyComponent = lazy(() => import('./HeavyComponent'));function App() {return (<Suspense fallback={<div>加载中...</div>}><HeavyComponent /></Suspense>);
}

Suspense 是并发渲染支持的重要基础之一。


4. useDeferredValue()

用于延迟某个值的变化,防止其触发高开销渲染。

const deferredInput = useDeferredValue(input);

可以搭配 input 实时搜索场景使用,提升体验。

在这里插入图片描述

useTransition 和 useDeferredValue 的区别

  1. 控制点不同
    • useTransition: 允许你包裹状态更新的逻辑(setState)。你明确指
      定哪个更新是低优先级的
    • useDeferredValue:允许你包裹一个值(通常是props或派生状态)。你关注的是值的延迟版本,而非更新过程。
  2. API 和反馈机制
    • useTransition返回isPending状态和startTransition函数。isPending可直接用于展示加载 UI。
    • useDeferredValue:仅返回一个延迟后的值。如需加载状态,通常需自行比较原始值和延迟值(e.g,text!=deferredText)
  3. 发起者视角
    • useTransition:主动行为
    • useDeferredValue:被动/响应式行为

🧩 四、实际应用场景举例

应用场景传统做法的问题React 18 的解决方案
用户输入时,触发大数据渲染输入卡顿、掉帧startTransition 异步更新结果
输入框绑定了复杂运算的数据实时更新导致卡顿useDeferredValue 缓更新
懒加载组件过慢首屏空白或阻塞渲染Suspense 延迟加载并展示 loading
SSR 流式渲染一次性渲染,TTFB 高React 18 支持 streaming(ReactDOMServer)

搜索/筛选大型列表:

在这里插入图片描述

外部数据源的图表/可视化:

图表接收频繁更新的 data prop,导致重绘耗时,引发卡顿。

在这里插入图片描述

编辑器草稿与实时预览

用户输入内容(高优先级),旁边的预览窗口根据输入实时渲染 Markdown 或复杂格式(低优先级)。

两者皆有可能,取决于状态组织方式:

  • useTransition:若编辑器和预览内容是分别的状态,用它包裹更
    新预览内容的状态。
  • useDeferredValue:若预览组件直接接收编辑器内容作 prop , 用
    它延迟预览组件的渲染

🎯 总结

特性说明
startTransition标记某些更新为可中断、可延迟
useTransition用于显示“挂起状态”
useDeferredValue推迟输入值更新,防止重复高开销渲染
Suspense组件级懒加载或延迟展示
createRoot启用并发渲染的前提

如果你希望我结合某个真实业务场景(比如表单输入、分页、搜索)给你写一个完整的 React18 并发特性 demo,也可以告诉我,我可以为你提供代码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/diannao/85944.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

FFMPEG 提取视频中指定起始时间及结束时间的视频,给出ffmpeg 命令

以下是提取视频中指定起始时间及结束时间的 ffmpeg 命令示例: bash 复制 ffmpeg -i input.mp4 -ss 00:01:30.00 -to 00:05:00.00 -c copy output.mp4 其中,-i input.mp4 是指定要处理的输入视频文件为 “input.mp4”。 -ss 00:01:30.00 表示指定视频的起始时间为 1 分 30 …

mybatis的if判断==‘1‘不生效,改成‘1‘.toString()才生效的原因

mybatis的xml文件中的if判断‘1’不生效&#xff0c;改成’1’.toString()才生效 Mapper接口传入的参数 List<Table> queryList(Param("state") String state);xml内容 <where><if test"state ! null and state 1">AND EXISTS(select…

AI 模型分类全解:特性与选择指南

人工智能&#xff08;AI&#xff09;技术正以前所未有的速度改变着我们的生活和工作方式。AI 模型作为实现人工智能的核心组件&#xff0c;种类繁多&#xff0c;功能各异。从简单的线性回归模型到复杂的深度学习网络&#xff0c;从文本生成到图像识别&#xff0c;AI 模型的应用…

01-python爬虫-第一个爬虫程序

开始学习 python 爬虫 第一个获取使用最多的网站-百度 源代码 并将源代码保存到文件中 from urllib.request import urlopenurl https://www.baidu.com resp urlopen(url)with open(baidu.html, w, encodingutf-8) as f:f.write(resp.read().decode(utf-8))知识点&#xf…

四六级监考《培训学习》+《培训考试》

1 线上注册 &#xff08;网址&#xff1a; https://passport.neea.edu.cn 2 登录培训平台参加线上必修课程学习和考核 &#xff08;平台网址&#xff1a; https://kwstudy.neea.edu.cn 注意选择学员入口&#xff09; 3 考试要求&#xff1a;考试成绩须达应到80分以上&#xf…

回顾Java与数据库的30年历程

当 Java 1.0 于 1996 年推出时&#xff0c;语言和互联网都与今天大不相同。当时&#xff0c;网络主要是静态的&#xff0c;而 Java 承诺通过注入交互式游戏和动画来为网络注入活力&#xff0c;这一承诺极具前景。根据 1995 年写给《连线》杂志的 David Banks 的说法&#xff0c…

simulink有无现成模块可以实现将三个分开的输入合并为一个[1*3]的行向量输出?

提问 simulink有无现成模块可以实现将三个分开的输入合并为一个[1*3]的行向量输出&#xff1f; 回答 Simulink 本身没有一个单独的模块能够直接将三个分开的输入合并成一个 [13] 行向量输出&#xff0c;但是可以通过 组合模块实现你要的效果。 ✅ 推荐方式&#xff1a;Mux …

代码训练LeetCode(24)数组乘积

代码训练(24)LeetCode之数组乘积 Author: Once Day Date: 2025年6月5日 漫漫长路&#xff0c;才刚刚开始… 全系列文章可参考专栏: 十年代码训练_Once-Day的博客-CSDN博客 参考文章: 238. 除自身以外数组的乘积 - 力扣&#xff08;LeetCode&#xff09;力扣 (LeetCode) 全…

NLP学习路线图(十七):主题模型(LDA)

在浩瀚的文本海洋中航行&#xff0c;人类大脑天然具备发现主题的能力——翻阅几份报纸&#xff0c;我们迅速辨别出"政治"、"体育"、"科技"等板块&#xff1b;浏览社交媒体&#xff0c;我们下意识区分出美食分享、旅行见闻或科技测评。但机器如何…

vue对axios的封装和使用

在 Vue 项目中&#xff0c;使用 axios 进行 HTTP 请求是非常常见的做法。为了提高代码的可维护性、统一错误处理和请求拦截/响应拦截逻辑&#xff0c;对axios进行封装使用。 一、基础封装&#xff08;适用于 Vue 2 / Vue 3&#xff09; 1. 安装 axios npm install axios2. 创…

HTML实现端午节主题网站:龙舟争渡,凭吊祭江诵君赋。

名人说:龙舟争渡,助威呐喊,凭吊祭江诵君赋。——苏轼《六幺令天中节》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 目录 一、项目概览:传统与现代的技术碰撞1. 核心特性一览2. 网站结构设计二、技术亮点深度解析1. 响应式布局的精妙设计2. CSS动画系统的…

【Redis】笔记|第9节|Redis Stack扩展功能

Redis Stack 扩展功能笔记&#xff08;基于 Redis 7&#xff09; 一、Redis Stack 概述 定位&#xff1a;Redis OSS 扩展模块&#xff08;JSON、搜索、布隆过滤器等&#xff09;&#xff0c;提供高级数据处理能力。核心模块&#xff1a; RedisJSON&#xff1a;原生 JSON 支持…

如何选择专业数据可视化开发工具?为您拆解捷码全功能和落地指南!

分享大纲&#xff1a; 1、捷码核心功能&#xff1a;4维能力支撑大屏开发 2、3步上手&#xff1a;可视化大屏开发操作路径 3、适配场景&#xff1a;8大行业已验证方案 在各行各业要求数字化转型时代&#xff0c;数据可视化大屏已成为众多企业数据驱动的核心工具。面对市场上繁杂…

测试W5500的第11步_使用ARP解析IP地址对应的MAC地址

本文介绍了基于W5500芯片的ARP协议实现方法&#xff0c;详细阐述了ARP请求与回复的工作机制。ARP协议通过广播请求和单播回复实现IP地址与MAC地址的映射&#xff0c;确保局域网设备间的可靠通信。文章提供了完整的STM32F10x开发环境下的代码实现&#xff0c;包括网络初始化、SP…

在树莓派上添加音频输入设备的几种方法

在树莓派上添加音频输入设备可以通过以下步骤完成&#xff0c;具体方法取决于设备类型&#xff08;如USB麦克风、3.5mm接口麦克风或HDMI音频输入&#xff09;。以下是详细指南&#xff1a; 1. 连接音频输入设备 USB麦克风/声卡&#xff1a;直接插入树莓派的USB接口。3.5mm麦克…

IDEA 打开文件乱码

问题&#xff1a;文件乱码 底部编码无法切换 解决方案&#xff1a; 第一步 使用Nodepad 查询文件编码 本项目设置为 转为 UTF-8 无 BOM 第二步&#xff1a;在 IntelliJ IDEA 中&#xff1a;右键点击文件 → File Encoding → 选择目标编码&#xff08;如 UTF-8&#xff09; 最…

float、double 这类 浮点数 相比,DECIMAL 是另一种完全不同的数值类型

和 float、double 这类**“浮点数”**相比&#xff0c;DECIMAL 是另一种完全不同的数值类型&#xff0c;叫做&#xff1a; ✅ DECIMAL 是什么&#xff1f; DECIMAL 是“定点数”类型&#xff08;fixed-point&#xff09;&#xff0c;用于存储精确的小数值&#xff0c;比如&…

Java应用10(客户端与服务器通信)

Java客户端与服务器通信 Java提供了多种方式来实现客户端与服务器之间的通信&#xff0c;下面我将介绍几种常见的方法&#xff1a; 1. 基于Socket的基本通信 服务器端代码 import java.io.*; import java.net.*;public class SimpleServer {public static void main(String…

pytorch基本运算-范数

引言 前序学习进程中&#xff0c;已经对pytorch基本运算有了详细探索&#xff0c;文章链接有&#xff1a; 基本运算 广播失效 乘除法和幂运算 hadamard积、点积和矩阵乘法 上述计算都是以pytorch张量为运算元素&#xff0c;这些张量基本上也集中在一维向量和二维矩阵&#x…

EasyRTC音视频实时通话助力新一代WebP2P视频物联网应用解决方案

一、方案背景​ 物联网技术深刻变革各行业&#xff0c;视频物联在智慧城市、工业监控等场景广泛应用。传统方案依赖中心服务器中转&#xff0c;存在传输效率低、网络负载大的问题。新一代WebP2P视频物联技术实现设备直连&#xff0c;降低网络压力并提升传输效率&#xff0c;成…