React組件簡介

組件

在 React 中,組件(Component) 是 UI 的基本構建塊。可以把它理解為一個獨立的、可復用的 UI 單元,類似于函數,它接受輸入(props),然后返回 React 元素來描述 UI。

組件的簡單使用

在 React 中,組件主要分為兩種:類組件和函數組件。但是在 React 18+ 之后,以不推薦使用類組件,而是推薦使用函數組件。

函數組件本質上是一個 Javascript 函數,然后返回一個 JSX 結構。函數組件的名字必須以大寫字母開頭,否則 React 會將其視為一個 HTML 標簽。

函數組件更簡單,它沒有 this, 編寫和閱讀更簡單,而狀態則是通過 React Hooks 來實現的。下面是一個簡單的函數組件的例子:

//  定義組件
function Button() {// 組件內部的邏輯return (<button>Click me</button>);
}

這樣我們就創建了一個 React 組件,接下來,我們可以在 App 組件中使用它:

function App() {return (<div><Button /></div>)
}

除了 Button 組件,App 組件本身也是組件,也就是說組件可以嵌套使用。

組件的特點

  1. 組件必須返回一個 JSX 結構(或 null)
  2. 組件名稱必須大寫(如 MyComponent,不能寫 myComponent)
  3. 可以組合嵌套(組件可以包含其他組件)
  4. 可以接收 props(用于傳遞數據)

組件的狀態

在 React 組件中,狀態(State) 是指組件內部可變的數據,用于控制組件的行為和 UI 的變化。當 state 發生變化 時,React 會自動重新渲染組件,更新 UI。

為什么需要狀態?

有些數據不會變,比如 props 傳遞過來的值,但有些數據是會隨用戶交互變化的,比如:

  • 計數器的數值
  • 按鈕的開關狀態
  • 輸入框中的內容

這些會變化的數據 就應該存到組件的 state 中。例如:

import { useState } from "react";function Counter() {// useState(0) 表示 count 初始值為 0const [count, setCount] = useState(0);return (<div><p>當前計數:{count}</p>{/* 點擊按鈕時,修改 count 值 */}<button onClick={() => setCount(count + 1)}>+1</button></div>);
}export default Counter;

當點擊 +1 按鈕時,會調用 setCount 方法,將 count 的值加 1,然后 React 會重新渲染組件,更新 UI。具體來說當組件的 state 發生變化時,React 執行以下流程:

  1. 調用 setState 或 useState 進行狀態更新
  2. React 觸發組件的重新渲染(函數組件會重新執行,類組件會觸發 render 方法
  3. 生成新的 Virtual DOM(虛擬 DOM)
  4. 比較新的 Virtual DOM 和舊的 Virtual DOM(Diffing 算法)
  5. 計算差異后更新真實 DOM(Reconciliation 過程)

React 通過 useState(或 setState)觸發狀態更新,然后采用 調度機制(Scheduler)+ 批量更新(Batching) 來通知瀏覽器進行重新渲染。這種機制類似于 Qt 的信號槽或者是發布-訂閱模式。但是 React 的更新機制與 Qt 的信號槽不同的是,React 的更新機制是異步的,而 Qt 的信號槽是同步的。

Virtual DOM 機制

React 并不會直接操作 真實 DOM(Real DOM),而是使用 Virtual DOM 來提升性能。

虛擬 DOM(Virtual DOM) 是 React 在內存中的 JavaScript 對象,它描述了 UI 結構。

每次 state 變化時,React 會重新創建一個新的 Virtual DOM。

Diffing 算法(Diff 算法)

React 通過 Diffing 算法 比較「新的 Virtual DOM」和「舊的 Virtual DOM」,找出不同點,只更新發生變化的部分,避免整個頁面的重新渲染。

Diff 算法流程

  1. 樹形對比

     如果新的 Virtual DOM 和舊的 Virtual DOM 不是相同的組件,則直接銷毀舊組件,創建新組件。如果它們是同一個組件,則繼續向下比較子元素。
    
  2. 屬性對比(Props Diffing)

     如果 props 發生變化,則更新對應的 DOM 屬性。
    
  3. 子元素對比(Children Diffing)

     使用Key 機制優化列表渲染(key 幫助 React 識別哪些元素是新增、刪除或移動的,我們在列表渲染中接觸過 key 機制)。
    

Reconciliation(協調過程)

React 在 Diffing 之后,使用 Reconciliation(協調過程) 將「最小的變更」應用到真實 DOM:

  • 僅修改需要更新的 DOM 節點
  • 不會重新創建整個 DOM 結構
  • 性能更高,避免不必要的操作

React 如何知道狀態發生了變化?

當我們調用 setState(類組件)或 useState(函數組件)時,React 內部執行以下操作:

  1. 記錄狀態變更

    React 維護著一個 state 和 nextState。

    當調用 setState(newState) 時,React 不會立即修改 state,而是先把 newState 放入更新隊列。

  2. 觸發調度(Scheduler 機制)

    React 不是立刻重新渲染,而是將更新任務提交給 Scheduler(調度器),并進行批處理優化。

  3. 標記 Fiber 節點為「需要更新」

    React 使用 Fiber 架構,每個組件對應一個 Fiber 節點,setState 會讓 Fiber 節點進入「更新狀態」,等待下一次渲染。

為什么 React 不是立即更新?

React 采用 批量更新(Batching) 機制:

  • 同一個事件循環內的多個 setState 只會觸發一次渲染,減少不必要的更新,提高性能。
  • React 18 引入 Concurrent Mode,可以延遲低優先級的更新,提高流暢度。

useState 修改狀態

我們還是以一個簡單的 Demo 為例,展示如何使用 useState 修改狀態:

import { useState } from "react";   // 引入 useState
function Counter() {const [count, setCount] = useState(0);   // 初始化 count 為 0return (<div><p>當前計數:{count}</p><button onClick={() => setCount(count + 1)}>+1</button><button onClick={() => setCount(count - 1)}>-1</button></div>)
}

const [count, setCount] = useState(0); 這行代碼就類似于發布訂閱模式中,訂閱者注冊自己所需要關注的事件或消息。這里可以理解為訂閱者注冊了 count 變化時,會收到通知,然后更新 count 的值。

在 React 中,useState 是一個 Hook,用于在函數組件中添加狀態。它返回一個數組,數組的第一個元素是當前狀態的值,第二個元素是一個函數,用于更新狀態。

直接改變 count 的值,并不會觸發組件的重新渲染,因為 React 是通過 setState 來觸發組件的重新渲染的。因此需要調用 setCount 來更新 count 的值,然后 React 會重新渲染組件,更新 UI。

多個狀態值管理

你可以在 useState 中存儲多個值,例如:

function UserInfo() {const [user, setUser] = useState({ name: "Alice", age: 25 });return (<div><p>姓名:{user.name}</p><p>年齡:{user.age}</p><button onClick={() => setUser({ ...user, age: user.age + 1 })}>生日+1</button></div>);
}

這里使用了 …user(展開運算符)來避免覆蓋 name,僅修改 age。

組件樣式控制

在 React 中,控制組件的樣式,可以直接在行內樣式中設置,也可以使用 className 屬性來設置類名,然后在 CSS 文件中定義樣式。在工程化中,一般是使用 className 來控制樣式。

行內樣式

在 React 中,你可以在行內樣式中設置樣式,例如:

<div style={{ color: 'red', fontSize: '16px' }}>Hello World</div>

在上面的例子中,style 屬性是一個對象,其中包含了 CSS 屬性及其值。你可以使用駝峰命名法來設置 CSS 屬性,例如 color 和 fontSize。如果覺得 style 屬性太長,可以定義一個變量來存儲樣式對象,然后使用變量來設置樣式。例如:

const style = {color: 'red',fontSize: '16px'
}
<div style={style}>Hello World</div>

通過 className 來控制樣式

在 React 中,你可以使用 className 屬性來控制組件的樣式,例如:

在 CSS 文件中,你可以定義一個類名為 my-class 的樣式,例如:

.my-class {color: red;font-size: 16px;
}

在組件中,你可以使用 className 屬性來設置類名,例如:

import './App.css';
<div className="my-class">Hello World</div>

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

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

相關文章

Kafka消息序列化深度革命:構建高性能、高安全的自定義編碼體系

一、突破默認序列化的桎梏 1.1 原生序列化器的致命缺陷 Kafka默認提供的StringSerializer/ByteArraySerializer在復雜場景下暴露三大痛點&#xff1a; 類型安全黑洞&#xff1a;字節流缺乏元數據描述&#xff0c;消費端解析如履薄冰版本兼容困境&#xff1a;數據結構變更導致…

向量數據庫與傳統數據庫的差異

向量數據庫是一種專門設計用于高效存儲、管理和檢索**向量數據&#xff08;高維數值數組&#xff09;**的數據庫系統。它針對非結構化數據&#xff08;如圖像、文本、音頻&#xff09;的特征進行優化&#xff0c;通過將數據轉化為向量嵌入&#xff08;embeddings&#xff09;&a…

自動化框架的設計與實現

一、自動化測試框架 在大部分測試人員眼中只要沾上“框架”&#xff0c;就感覺非常神秘&#xff0c;非常遙遠。大家之所以覺得復雜&#xff0c;是因為落地運用起來很復雜&#xff1b;每個公司&#xff0c;每個業務及產品線的業務流程都不一樣&#xff0c;所以就導致了“自動化…

SpringBoot 3+ Lombok日志框架從logback改為Log4j2

r要將Spring Boot 3項目中的日志框架從Logback切換到Log4j2&#xff0c;并配置按日期滾動文件和控制臺輸出&#xff0c;請按照以下步驟操作&#xff1a; 步驟 1&#xff1a;排除Logback并添加Log4j2依賴 在pom.xml中修改依賴&#xff1a; <dependencies><!-- 排除默…

①、環境準備-主流技術(IPS/FW/主備-主主快速切換)

主流技術&(IPS/FW/主備-主主快速切換&#xff09; 一、RBM主備方案 RBM-FW-P 主配置內容介紹-注釋 remote-backup group 含義&#xff1a;定義了一個遠程備份組。這表明設備支持某種形式的遠程備份功能&#xff0c;用于在設備之間同步配置或數據。data-channel interface …

量化交通擁堵

指數&#xff1a; 基于嚴重擁堵里程比的指數和基于出行時間比的指數。 評價指標是飽和度&#xff08;VC比&#xff09;&#xff0c;它表示交通量與通行能力的比值。 飽和度可分為道路飽和度和路口飽和度。道路飽和度還會進一步分級&#xff0c;有四檔和六檔之分。 城市道路和…

PDF與Markdown的量子糾纏:一場由VLM導演的文檔界奇幻秀

緣起:當格式界的"泰坦尼克號"撞上"黑客帝國" 某個月黑風高的夜晚,在"二進制酒吧"的霓虹燈下: PDF(西裝革履地晃著威士忌): “我的每一頁都像瑞士手表般精密,連華爾街的禿鷲都為我傾倒!” Markdown(穿著帶洞的拖鞋): “得了吧老古董!…

【neo4j數據導出并在其他電腦導入】

停止服務 neo4j stop 導出 neo4j-admin database dump neo4j --to-path"C:\Users\12901\Downloads\test folder" 導入 將 .dump 文件放在一個目錄中 mkdir /root/dump-directory mv /root/neo4j.dump /root/dump-directory/ 使用包含 .dump 文件的目錄路徑作為 …

前端使用WPS WebOffice 做在線文檔預覽與編輯

先附上官網 WebOffice SDK 1、在下面這個地方找到jdk&#xff0c;然后下載 按照 2、只需要把jdk下載下來&#xff0c;放到項目中&#xff0c;然后引入到項目中就可以了&#xff0c;在wps 官網創建個應用&#xff0c;然后把appId放到代碼中就可以了&#xff0c;等待后端把回調…

跨語言微服務架構(Java、Python)——“API中臺”

文章目錄 一、引言二、系統架構概述2.1 統一單點登錄&#xff08;SSO&#xff09;與權限管理設計2.2 API中臺與數據中臺的融合2.3 跨語言適配器與 JWT 認證機制 三、技術細節與工具選型3.1 SSO 系統的選型與實現3.2 微服務架構與 API 中臺的實現3.3 跨語言適配器實現與技術難點…

DeepSeek V3-0324升級:開啟人機共創新紀元

一、技術平權&#xff1a;開源協議重構AI權力格局 DeepSeek V3選擇MIT協議開源6850億參數模型&#xff0c;本質上是一場針對技術壟斷的“數字起義”。這一決策的深層影響在于&#xff1a; 商業邏輯的重構 閉源AI公司依賴API收費的商業模式面臨根本性挑戰。當頂級模型能力可通過…

QOpenGLWidget視頻畫面上繪制矩形框

一、QPainter繪制 在QOpenGLWidget中可以繪制,并且和OpenGL的內容疊在一起。paintGL里面繪制完視頻后,解鎖資源,再用QPainter繪制矩形框。這種方式靈活性最好。 void VideoGLWidget::paintGL() {glClear(GL_COLOR_BUFFER_BIT);m_program.bind();//繪制視頻數據// 解綁VAOg…

3.3 Taylor公式

1.定義 1.1 taylor公式 1.2 麥克勞林公式 1.3 推論 1.4 拉格朗日余項和皮亞諾型余項 2. 例題 3.幾種特殊函數的麥克勞林展開

CEF 給交互函數, 添加控制臺是否顯示交互參數log開關

CEF 控制臺添加一函數,枚舉 注冊的供前端使用的CPP交互函數有哪些 CEF 多進程模式時,注入函數,獲得交互信息-CSDN博客 這兩篇文章,介紹了注入函數,在控制臺中顯示 各自提供的交互函數信息。 有些場景下,我們還需要更詳細的信息,比如想知道 彼此傳遞的參數, 如果每次調…

QTcpSocket多線程連接慢問題

20250325記錄 環境&#xff1a;Qt5.14.2 64位 msvc編譯 在多線程環境下&#xff0c;使用QTcpSocket實現客戶端&#xff0c;發現在少部分電腦上&#xff0c;連接時間過長&#xff0c;定時器檢查套接字狀態時&#xff0c;發現連接處于QAbstractSocket::ConnectingState狀態。 …

IntelliJ IDEA創建Maven工程

1、創建空工程 1&#xff09;創建 2&#xff09;配置JDK和Maven 2、創建Maven工程 3、Maven工程結構簡介 1&#xff09;目錄 pom.xml 2&#xff09;窗口 4、參考 08.IDEA配置本地Maven軟件_嗶哩嗶哩_bilibili

(UI自動化測試web端)第二篇:元素定位的方法_css定位之class選擇器

看代碼里的【find_element_by_css_selector( )】( )里的表達式怎么寫&#xff1f; 文章介紹了第二種寫法class選擇器。你要根據網頁中的實際情況來判斷自己到底要用哪一種方法來進行元素定位。每種方法都要多練習&#xff0c;全都熟了之后你在工作當中使用起來元素定位時&#…

加新題了,MySQL 8.0 OCP 認證考試 題庫更新

MySQL 8.0 OCP 認證考試 題庫更新 MySQL 8.0 Database Administrator 考試科目&#xff1a;1Z0-908 近期發現&#xff0c;MySQL OCP認證考試題庫發生變化&#xff0c;出現了很多新題&#xff0c;對此&#xff0c;CUUG專門收集整理了最新版本的MySQL考試原題&#xff0c;并會給…

基于JavaWeb的圖書管理系統(SSM框架)

有需要請加文章底部Q哦 可遠程調試 基于JavaWeb的圖書管理系統(SSM框架) 一 介紹 此圖書管理系統基于Java(SSM框架)開發&#xff0c;數據庫mysql&#xff0c;前端bootstrap。系統角色分為用戶和管理員。 技術棧&#xff1a;Javaweb(SpringSpringMVCMyBatis)MavenMySQLIDEA 二…

Google Benchmark性能測試

Google Benchmark性能測試 Google Benchmark 是一個用于 C 的微基準測試框架&#xff0c;專為測量小塊代碼的性能而設計。它提供了一種簡單而強大的方式來編寫、運行和分析基準測試&#xff0c;幫助開發人員識別性能瓶頸并優化代碼。本教程將從安裝和基本用法開始&#xff0c;…