【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
繁體地址,請注明出處:http://hk.pswp.cn/diannao/85944.shtml
英文地址,請注明出處:http://en.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;成…