ReactJS 中的 JSX工作原理

文章目錄

  • 前言
    • ? 1. JSX 是什么?
    • 🔧 2. 編譯后的樣子(核心機制)
    • 🧱 3. `React.createElement` 做了什么?
    • 🧠 4. JSX 與組件的關系
    • 🔄 5. JSX 到真實 DOM 的過程
    • 📘 6. JSX 與 Fragment、條件渲染等底層行為
    • ?? 7. 注意事項
    • ? 總結
  • JSX 編譯后如何通過 Fiber 架構驅動渲染更新
    • ? 一、React 渲染整體流程概覽(React 18+)
    • 🧠 二、什么是 Fiber 架構?
      • 📦 一個 Fiber 節點結構簡化如下:
    • 🔄 三、Reconciliation(協調 / diff)機制
      • Diff 規則核心簡化:
    • ?? 四、Commit 階段(更新真實 DOM)
    • ?? 五、Concurrent Mode(React 18)
      • 🌟 調度示意(非阻塞渲染):
    • 📌 六、雙緩沖機制(雙 Fiber Tree)
    • 🎯 七、性能優化的啟示
    • ? 總結:JSX 到 DOM 的底層機制主線
  • ?? React Fiber 調度與中斷機制:時間切片、優先級調度、任務恢復
    • ? 1. 為什么需要中斷渲染?
      • 問題:
    • ? 2. Fiber 如何解決這個問題?
      • 🎯 利用:
    • 📦 3. 任務調度:Scheduler 的優先級系統
    • ? 4. 時間切片機制(Time Slicing)
    • 🔁 5. 中斷與恢復機制
    • ?? 6. Concurrent 模式的核心優勢
    • 🧠 7. 示例:startTransition 與中斷渲染
    • ? 8. 總結:Fiber 調度機制的精髓
    • 📘 延伸(可選深入)


前言

ReactJS 中的 JSX(JavaScript XML)看起來像 HTML,但它其實只是語法糖,在底層是被編譯成 React.createElement(...) 調用的 JavaScript 代碼。理解其底層機制對優化性能、調試問題、使用 Hooks 等非常重要。


? 1. JSX 是什么?

JSX 是 JavaScript 的語法擴展,允許你這樣寫 UI:

const element = <h1>Hello, world!</h1>;

它看起來像 HTML,但不是。它不會被瀏覽器直接執行,而是會在構建階段被轉譯為 JavaScript。


🔧 2. 編譯后的樣子(核心機制)

這段代碼:

const element = <h1 className="title">Hello</h1>;

會被 Babel 編譯為:

const element = React.createElement('h1',{ className: 'title' },'Hello'
);

等價于:

{type: 'h1',props: {className: 'title',children: 'Hello'}
}

最終,React 用這些對象來構建虛擬 DOM(Virtual DOM)。


🧱 3. React.createElement 做了什么?

它會返回一個React 元素對象

{$$typeof: Symbol(react.element),type: 'h1',key: null,ref: null,props: {className: 'title',children: 'Hello'},_owner: null
}

這是一個純 JS 對象,描述了 UI 的結構。不是 DOM 節點,還沒有真正渲染。


🧠 4. JSX 與組件的關系

JSX 中也可以使用組件:

<MyButton text="Click me" />

被編譯為:

React.createElement(MyButton, { text: "Click me" });

最終調用你自己寫的 MyButton(props) 函數,返回另一個 createElement(...)


🔄 5. JSX 到真實 DOM 的過程

  1. JSX 被編譯為 React.createElement(...)
  2. React 構建虛擬 DOM 樹
  3. React 將虛擬 DOM diff(比對)舊的 DOM 樹
  4. React 使用 DOM API 更新真實 DOM(插入、刪除、替換節點)

📘 6. JSX 與 Fragment、條件渲染等底層行為

  • <></>React.createElement(React.Fragment, null, ...)
  • 條件渲染:{condition && <div>Yes</div>} → 三元或邏輯判斷
  • 循環渲染:{list.map(item => <li>{item}</li>)} → 多次 createElement 調用

?? 7. 注意事項

特性底層意義
JSX 只能有一個根節點因為 React.createElement 只能返回一個元素
不支持 if 語句直接寫在 JSXJSX 是表達式,需要用三元或外部邏輯
自閉和標簽 <MyComp />轉譯為 React.createElement(MyComp)
不能直接渲染對象[object Object] 錯誤是因為 createElement 接收了非法 children

? 總結

概念作用
JSXReact 的語法糖,用來描述 UI 結構
Babel把 JSX 編譯為 React.createElement()
React.createElement創建虛擬 DOM 描述對象
虛擬 DOM一個 JS 對象樹,最終映射為真實 DOM
渲染機制Diff + 更新 DOM 節點(最小化操作)

JSX 編譯后如何通過 Fiber 架構驅動渲染更新

這一主線,系統講解 React 的底層工作機制,包括:


? 一、React 渲染整體流程概覽(React 18+)

graph TD
A[JSX] --> B[createElement]
B --> C[構建虛擬 DOM]
C --> D[Fiber 架構構建 Fiber Tree]
D --> E[Reconciliation(diff)]
E --> F[Commit 階段:更新真實 DOM]

🧠 二、什么是 Fiber 架構?

Fiber 是 React 從 v16 開始的核心架構,其主要目標是:

  • 支持任務中斷(可暫停)
  • 支持異步渲染(并發模式)
  • 增強調度控制
  • 支持優先級(Urgent、Normal、Idle)

Fiber = 一種“工作單元”結構,用鏈表組織虛擬 DOM,便于逐個處理、可打斷、可恢復


📦 一個 Fiber 節點結構簡化如下:

interface Fiber {type: string | FunctionComponentstateNode: HTMLElement | nullchild: Fiber | nullsibling: Fiber | nullreturn: Fiber | nullalternate: Fiber | null // 雙緩存機制effectTag: 'UPDATE' | 'PLACEMENT' | 'DELETION'
}

🔄 三、Reconciliation(協調 / diff)機制

目的:比較新舊 virtual DOM,找到最小變更,生成 effectList 用于更新真實 DOM。

Diff 規則核心簡化:

  • 同層比較:只比較同級節點
  • Key 區分同類型組件:用于 map 渲染性能優化
  • 類型不同 → 全替換
  • 類型相同 → 嘗試復用

?? 四、Commit 階段(更新真實 DOM)

當 Fiber 樹構建完畢后,進入 commit 階段:

// commitWork
switch (fiber.effectTag) {case 'PLACEMENT': // 插入parent.appendChild(fiber.stateNode);break;case 'UPDATE': // 屬性或內容變更updateDOM(fiber.stateNode, oldProps, newProps);break;case 'DELETION':parent.removeChild(fiber.stateNode);break;
}

?? 五、Concurrent Mode(React 18)

React 18 引入并發渲染模式,依賴 Fiber 實現:

特性描述
startTransition標記可中斷更新(非緊急)
自動批處理setState 自動分組,不再需要 unstable_batchedUpdates
useDeferredValue延遲非關鍵狀態同步更新
useTransition標記 UI “pending” 狀態,支持 loading skeleton 等過渡體驗
ReactDOM.createRoot默認進入 Concurrent 模式

🌟 調度示意(非阻塞渲染):

startTransition(() => {setValue(input);
})

React 會調度優先級高的操作(如輸入)先渲染,低優先的任務稍后處理。


📌 六、雙緩沖機制(雙 Fiber Tree)

React 使用 currentworkInProgress 兩棵 Fiber Tree,交替使用:

current正在顯示的 UI
workInProgress當前計算的新狀態

當 Reconciliation 完成,React 會“交換”兩棵樹,實現 快照切換


🎯 七、性能優化的啟示

場景原因優化策略
大量列表重復渲染Key 設計不當導致全部 diff用穩定 Key
卡頓嚴重所有狀態更新同步使用 startTransition, useDeferredValue
多組件嵌套,重渲染過多props 未 memo使用 React.memouseMemo, useCallback
復雜條件渲染JSX 重計算多使用懶加載 React.lazy, Suspense

? 總結:JSX 到 DOM 的底層機制主線

階段關鍵內容
編譯JSX → createElement → 虛擬 DOM
構建Fiber 樹結構,鏈表連接
diffReconciliation 識別變化
更新commit 階段執行 effect list 操作真實 DOM
并發Fiber 允許中斷、恢復、優先級調度
優化利用 Hook + memo + key + transition

?? React Fiber 調度與中斷機制:時間切片、優先級調度、任務恢復

React Fiber 架構最大的突破之一就是它將渲染任務拆分為“工作單元”(Fiber 節點),并使用瀏覽器的空閑時間或非阻塞方式來執行這些任務。


? 1. 為什么需要中斷渲染?

問題:

React 早期(v15 及以前)渲染是同步的:

ReactDOM.render(<App />, root);

如果組件樹很大,JS 線程會被“卡死”,導致:

  • 輸入卡頓
  • 動畫掉幀
  • 無法響應用戶操作

? 2. Fiber 如何解決這個問題?

🧠 核心思想:把渲染拆成很多小任務,用瀏覽器空閑時間分批執行,并可中途暫停與恢復。

🎯 利用:

requestIdleCallback(callback)

或(React 18 起)用:

scheduler.unstable_scheduleCallback(priority, callback)

📦 3. 任務調度:Scheduler 的優先級系統

React 使用內部調度器(scheduler)給任務分配優先級:

調度級別描述示例
Immediate (最高)立刻執行setState 同步
UserBlocking用戶操作相關輸入、點擊
Normal默認更新內容變化
Low非關鍵動畫、日志
Idle不重要預加載

? 4. 時間切片機制(Time Slicing)

Fiber 會把任務拆成一個個 unit of work,然后循環調度:

while (nextUnitOfWork && shouldYield() === false) {nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
}

shouldYield() 檢查是否要讓位給瀏覽器,防止掉幀。

function shouldYield() {return performance.now() >= deadline;
}

🔁 5. 中斷與恢復機制

如果 shouldYield()true,Fiber 會 中斷當前工作,然后把當前狀態保存在 workInProgress 上,下次從這個點繼續:

// workInProgress 保存當前 fiber 的指針鏈表狀態

瀏覽器空閑后,React 會再次調度:

requestIdleCallback(workLoop)

?? 6. Concurrent 模式的核心優勢

能力說明
? 中斷渲染過程可被暫停
🔁 恢復下一幀繼續渲染剩余部分
?? 優先級用戶輸入優先渲染,非關鍵可延后
🎨 更流暢輸入不卡頓,動畫更自然
🧠 更智能可實現并行 diff、預渲染、Suspense fallback 等功能

🧠 7. 示例:startTransition 與中斷渲染

import { startTransition } from 'react'function handleInput(e) {const value = e.target.value// 非緊急更新,允許中斷startTransition(() => {setFilteredList(filterBigList(value))})
}

用戶打字不會因為 setFilteredList() 而卡頓,因為這是一個“可中斷更新”。


? 8. 總結:Fiber 調度機制的精髓

內容
拆分Fiber 把渲染任務拆成小單元
調度使用 scheduler 或 requestIdleCallback 進行執行調度
中斷shouldYield() 決定是否讓步給瀏覽器主線程
恢復保存中間狀態于 Fiber,支持恢復渲染
優先級按任務重要程度進行排序調度,保障交互流暢性

📘 延伸(可選深入)

如果你還想進一步了解:

  1. Lane Model(React 18 調度核心)
  2. React Scheduler 實現(源碼級)
  3. Suspense + Fiber 如何協同暫停渲染樹
  4. Concurrent Features:如 React.lazy, Streaming SSR

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

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

相關文章

Spring Advisor增強規則實現原理介紹

Spring Advisor增強規則實現原理介紹 一、什么是 Advisor&#xff1f;1. Advisor 的定義與本質接口定義&#xff1a; 2. Advisor 的核心作用統一封裝切點與通知構建攔截器鏈的基礎實現增強邏輯的靈活組合 二. Sprin當中的實現邏輯1 Advisor 接口定義2 PointcutAdvisor 接口定義…

小程序32-簡易雙向數據綁定

在WXML中&#xff0c;普通屬性的綁定是單向的&#xff0c;例如:<input value"{{value}}" /> 如果希望用戶輸入數據的同時改變data中的數據&#xff0c;可以借助簡易雙向綁定機制。在對應屬性之前添加model:前綴即可: 例如<input model:value"{{value}…

Nginx網站服務:從入門到LNMP架構實戰

&#x1f3e1;作者主頁&#xff1a;點擊&#xff01; Nginx-從零開始的服務器之旅專欄&#xff1a;點擊&#xff01; &#x1f427;Linux高級管理防護和群集專欄&#xff1a;點擊&#xff01; ??創作時間&#xff1a;2025年5月30日14點22分 前言 說起Web服務器&#xff0c…

【maker-pdf 文檔文字識別(包含ocr),安裝使用完整教程】

安裝環境 conda create -n maker-pdf python3.12 conda activate marker-pdf pip install modelscope pip install marker-pdf -U下載模型 from modelscope import snapshot_downloadmodel_root "models" snapshot_download("Lixiang/marker-pdf", loca…

C# 類和繼承(所有類都派生自object類)

所有類都派生自object類 除了特殊的類object&#xff0c;所有的類都是派生類&#xff0c;即使它們沒有基類規格說明。類object是唯 一的非派生類&#xff0c;因為它是繼承層次結構的基礎。 沒有基類規格說明的類隱式地直接派生自類object。不加基類規格說明只是指定object為 基…

尚硅谷redis7 90-92 redis集群分片之集群擴容

90 redis集群分片之集群擴容 三主三從不夠用了&#xff0c;進行擴容變為4主4從 問題&#xff1a;1.新建兩個redis實例&#xff0c;怎么加入原有集群&#xff1f;2.原有的槽位分3段&#xff0c;又加進來一個槽位怎么算&#xff1f; 新建6387、6388兩個服務實例配置文件新建后啟…

尚硅谷-尚庭公寓部署文檔

文章目錄 整合版部署文檔部署架構圖1. 項目目錄結構增加注釋的 Dockerfile 配置(1) 后端服務1 Dockerfile (backend/service1/Dockerfile)(2) 后端服務2 Dockerfile (backend/service2/Dockerfile) Dockerfile 配置說明重要注意事項3. Nginx 配置(1) 主配置文件 (nginx/nginx.c…

Android Studio 介紹

如何關閉或徹底刪除一個工程 基于Android Studio的android入門——如何關閉或徹底刪除一個工程 搜索內容 Android Studio高效指南&#xff1a;快速查找技巧大揭秘 build命令&#xff1a;gradle app:assembleDebug 命令解析 1. 命令結構與作用 核心功能&#xff1a;該命令…

JAVA與C語言之間的差異(一)

一、代碼習慣以及主函數 JAVA中{在使用的時候不要換行 public static void main(String[] args) {int[] array {1, 2, 3};for(int i 0; i < array.length; i){System.out.println(array[i] " ");}} 其次&#xff0c;以main函數為主函數&#xff1a; public …

華為OD機試真題——開放日活動/取出盡量少的球(2025A卷:200分)Java/python/JavaScript/C++/C語言/GO六種最佳實現

2025 A卷 200分 題型 本文涵蓋詳細的問題分析、解題思路、代碼實現、代碼詳解、測試用例以及綜合分析; 并提供Java、python、JavaScript、C++、C語言、GO六種語言的最佳實現方式! 本文收錄于專欄:《2025華為OD真題目錄+全流程解析/備考攻略/經驗分享》 華為OD機試真題《開放…

我的3種AI寫作節奏搭配模型,適合不同類型寫作者

—不用內耗地高效寫完一篇內容&#xff0c;原來可以這樣搭配AI ?? 開場&#xff1a;為什么要“搭配節奏”寫作&#xff1f; 很多人以為用AI寫作&#xff0c;就是丟一句提示詞&#xff0c;然后“等它寫完”。 但你有沒有遇到這些情況&#xff1a; AI寫得很快&#xff0c;學境…

【知識點】第1章:程序設計基本方法

文章目錄 知識點整理計算機的概念程序設計語言Python 語言概述Python 語言開發環境配置程序的基本編寫方法 練習題簡答題判斷題 知識點整理 計算機的概念 計算機的定義&#xff1a;計算機是根據指令操作數據的設備。 計算機的兩個基本特性&#xff1a; 功能性&#xff1a;計…

const ‘不可變’到底是值不變還是地址不變

const的基礎規則 聲明時必須初始化? const a; // ? 報錯&#xff1a;Missing initializer in const declaration const b 10; // ? 正確塊級作用域?&#xff08;const 的作用域僅限于聲明它的代碼塊&#xff09; if (true) {const x 100; } console.log(x); // ? 報錯…

Netty 實戰篇:為自研 RPC 框架加入異步調用與 Future 支持

我們在上篇實現了一個輕量級 RPC 框架&#xff0c;現在要進一步優化 —— 加入異步響應支持&#xff0c;讓 RPC 通信變得真正高效、非阻塞、支持并發。 一、為什么需要異步調用&#xff1f; 上篇的 RPC 框架是“同步阻塞”的&#xff1a; 每次發送請求后&#xff0c;必須等待服…

for(auto a:b)和for(auto a:b)的區別

#include<iostream> using namespace std; int main() {string s( "hello world" );for (auto c:s)c t ;cout<<s<<endl; //結果為hello worldfor (auto &c:s)c t ;cout<<s<<endl; //結果為ttttttttttt }for(auto a:b)中b為一…

超級對話2:大跨界且大綜合的學問融智學應用場景述評(不同第三方的回應)之二

摘要&#xff1a;《人機協同文明升維行動框架》提出以HIAICI/W公式推動認知革命&#xff0c;構建三大落地場景&#xff1a;1&#xff09;低成本認知增強神經接口實現300%學習效率提升&#xff1b;2&#xff09;全球學科活動化閃電戰快速轉化知識體系&#xff1b;3&#xff09;人…

多方法解決MNIST數字識別

全連接層 import torch from torchvision import datasets, transforms import torch.nn as nn import torch.optim as optim from tqdm import tqdm # 用于進度條顯示 import os# 定義數據預處理(標準化+Tensor轉換) transform = transforms.Compose([transforms.ToTensor…

安裝 Node.js 和配置 cnpm 鏡像源

一、安裝 Node.js 方式一&#xff1a;官網下載&#xff08;適合所有系統&#xff09; 訪問 Node.js 官網 推薦選擇 LTS&#xff08;長期支持&#xff09;版本&#xff0c;點擊下載安裝包。 根據系統提示一步步完成安裝。 方式二&#xff1a;通過包管理器安裝&#xff08;建…

vue 自定義組件的事件綁定

基本知識點 &#x1f3af;什么是自定義事件 自定義事件是子組件向父組件發送消息的機制&#xff0c;通常用于通知父組件發生了某些行為或狀態變化。 &#x1f4cc; 基本語法 子組件觸發事件&#xff08;$emit&#xff09; this.$emit(事件名, 參數);或在 const emit de…

進程同步機制-信號量機制-記錄型信號量機制中的的wait和signal操作

wait和signal是記錄型信號量機制中用于實現進程同步與互斥的兩個重要操作&#xff0c; wait 操作 wait(semaphores *S) {S->value --;if (S->value<0) block(S->list) }請求資源&#xff1a;S->value --; 這一步表示進程請求一個單位的資源&#xff0c;將信號…