動態UI的秘訣:React中的條件渲染

動態UI的秘訣:React中的條件渲染

作者:碼力無邊

各位React探險家,歡迎回到我們的《React奇妙之旅》!我是你們的老朋友碼力無邊。在之前的旅程中,我們已經學會了如何創建組件、傳遞數據(Props)、管理內部狀態(State),甚至如何與外部世界交互(useEffect)。我們的組件已經變得相當強大和動態了。

但是,一個用戶界面很少是一成不變的。我們經常需要根據不同的情況,向用戶展示不同的內容。比如:

  • 用戶登錄了,就顯示“歡迎回來,[用戶名]”,否則就顯示“請登錄”按鈕。
  • 數據正在加載中,就顯示一個“加載中…”的提示,加載完成后再顯示數據列表。
  • 購物車里有商品,就顯示商品列表和總價,否則就顯示“您的購物車是空的”。

這種根據特定條件來決定渲染哪個UI部分的技術,就是我們今天要探索的核心——條件渲染(Conditional Rendering)

條件渲染是構建動態和響應式用戶界面的基石。掌握了它,你就能像一位戲劇導演一樣,根據劇情的發展(應用的狀態),精確地控制舞臺上(頁面上)哪個“演員”(組件)該上場,哪個該退場。今天,我們將學習React中實現條件渲染的幾種主流“魔法”,從簡單直接到優雅靈活,總有一款適合你!

第一章:最樸素的魔法 —— if/else 語句

我們是JavaScript開發者,最熟悉、最直觀的條件判斷工具莫過于if...else語句。在React組件中,我們當然也可以使用它。

但是,請記住一個關鍵點:if/else是語句(Statement),而不是表達式(Expression)。這意味著你不能直接把它寫在JSX的花括號{}里面。

正確的做法是,在組件函數的return語句之前,使用if/else來準備好要渲染的內容,然后將結果渲染出來。

讓我們來看一個經典的登錄狀態切換的例子:

import React from 'react';function Greeting({ isLoggedIn }) {let content; // 聲明一個變量來存放要渲染的JSXif (isLoggedIn) {content = <h1>歡迎回來,尊貴的用戶!</h1>;} else {content = <h1>請先登錄</h1>;}return (<div>{content} {/* 在JSX中渲染這個變量 */}</div>);
}// 在App.jsx中使用
function App() {const [loggedIn, setLoggedIn] = React.useState(false);return (<div><Greeting isLoggedIn={loggedIn} /><button onClick={() => setLoggedIn(!loggedIn)}>{loggedIn ? '退出登錄' : '點擊登錄'}</button></div>);
}

優點:

  • 可讀性強:對于剛接觸React的開發者來說,這種方式非常直觀,和傳統的JavaScript邏輯沒有區別。
  • 處理復雜邏輯:當你的條件分支非常多,邏輯很復雜時(比如有多個else if),使用if/else結構會讓代碼的層次更清晰。

缺點:

  • 代碼略顯冗長:需要一個額外的變量,并且把渲染邏輯和JSX結構分開了。對于簡單的條件判斷,有點“殺雞用牛刀”。

第二章:最優雅的魔杖 —— 三元運算符 ? :

當你的條件渲染場景是“二選一”時,JavaScript的三元條件運算符(condition ? exprIfTrue : exprIfFalse)將成為你的最佳拍檔。

三元運算符是一個表達式,這意味著它可以直接嵌入到JSX的花括號{}中,讓我們的代碼變得極其緊湊和優雅。

讓我們用三元運算符來重構上面的Greeting組件:

import React from 'react';function Greeting({ isLoggedIn }) {return (<div>{isLoggedIn ? <h1>歡迎回來,尊貴的用戶!</h1> : <h1>請先登錄</h1>}</div>);
}

哇! 代碼是不是瞬間清爽了很多?我們把條件邏輯直接寫在了需要它的地方。這種寫法在React社區中非常流行,你應該盡快熟悉它。

實踐場景

  • 切換按鈕的文本:{isEditing ? '保存' : '編輯'}
  • 切換CSS類名:className={isActive ? 'active' : ''}
  • 根據加載狀態顯示不同組件:{isLoading ? <Spinner /> : <DataList />}

優點:

  • 簡潔緊湊:代碼量少,邏輯和視圖結合得更緊密。
  • 可以直接嵌入JSX:這是它相對于if/else最大的優勢。

缺點:

  • 不適合復雜邏輯:如果嵌套多層三元運算符,代碼會變得像“天書”一樣難以閱讀,這時應該回歸if/else

第三章:最精準的狙擊 —— 邏輯與 && 運算符

現在,我們面臨一種新的場景:如果滿足某個條件,就渲染某個東西;如果不滿足,就什么也不渲染。

比如,一個通知組件,只有當有未讀消息時,才顯示一個紅點徽章。

你當然可以用三元運算符來實現:{count > 0 ? <Badge count={count} /> : null}。當條件為false時,我們返回null。在React中,渲染nullundefinedfalse不會在DOM中產生任何輸出,這完全可行。

但是,我們有更簡潔的“語法糖”——邏輯與&&運算符。

在JavaScript中,true && expression總是返回expression,而false && expression總是返回false。React利用了這個特性。

import React from 'react';function Mailbox({ unreadMessages }) {const count = unreadMessages.length;return (<div><h1>您的收件箱</h1>{count > 0 && <h2>您有 {count} 條未讀消息。</h2>}{/* 如果count為0,整個&&表達式返回0(falsy),React不會渲染任何東西 */}</div>);
}// 在App.jsx中使用
function App() {const messages = ['React 很好', 'Vue 也不錯'];const noMessages = [];return (<div><Mailbox unreadMessages={messages} /><hr /><Mailbox unreadMessages={noMessages} /></div>);
}

工作原理

  • count > 0true時,&&運算符會繼續計算并返回右邊的表達式(即<h2>...</h2>),React會將其渲染出來。
  • count > 0false時,&&運算符會“短路”,立即返回左邊的false值,React會忽略它,不渲染任何東西。

優點:

  • 極度簡潔:是處理“有或無”場景的最簡便寫法。

?? 一個必須注意的“陷阱”:
&&左側的表達式結果如果是數字0,要特別小心!因為0 && expression會返回0,而React會把數字0渲染到頁面上

? 錯誤示范:
{messageCount && <MessageList />} // 如果messageCount0,頁面上會出現一個孤零零的0

? 正確規避:
確保&&左側是一個純粹的布爾值。
{messageCount > 0 && <MessageList />} // messageCount > 0的結果永遠是truefalse

第四章:終極武器 —— 封裝成獨立的組件

當你的條件渲染邏輯變得越來越復雜,甚至開始影響到當前組件的可讀性時,一個最佳的重構策略就是:將條件渲染的邏輯封裝到一個新的、獨立的組件中。

假設我們有一個頁面,根據用戶的權限等級('guest', 'user', 'admin')來顯示不同的控制面板。

不好的寫法(把所有邏輯都堆在App組件里):

function App() {const [userRole, setUserRole] = React.useState('admin');return (<div>{/* 巨型三元運算符或if/else塊 */}{userRole === 'guest' ? (<GuestDashboard />) : userRole === 'user' ? (<UserDashboard />) : userRole === 'admin' ? (<AdminDashboard />) : null}</div>);
}

這樣的App組件承擔了太多的職責,顯得非常臃腫。

? 優雅的重構:

創建一個專門負責“路由”的組件Dashboard

import React from 'react';
import GuestDashboard from './GuestDashboard';
import UserDashboard from './UserDashboard';
import AdminDashboard from './AdminDashboard';function Dashboard({ userRole }) {if (userRole === 'admin') {return <AdminDashboard />;}if (userRole === 'user') {return <UserDashboard />;}return <GuestDashboard />; // 默認顯示訪客面板
}// 現在App組件變得非常清爽
function App() {const [userRole, setUserRole] = React.useState('admin');return (<div><h1>我的應用</h1><Dashboard userRole={userRole} /></div>);
}

通過這種方式,App組件只關心傳遞userRole,而Dashboard組件則專門負責根據這個role來決定渲染哪個具體的面板。每個組件都職責單一,代碼的可讀性和可維護性大大提高。這體現了React組件化和單一職責原則的精髓。

總結:選擇最合適的“魔法”

今天,我們學習了在React中實現條件渲染的四種強大技術。它們沒有絕對的好壞之分,只有在特定場景下的適用性差異。

讓我們來做一個快速的回顧,幫你建立一個決策模型:

  1. 當你有復雜的、多分支的條件邏輯時(多個else if

    • 首選:在return之前使用**if/else語句**,保持代碼的清晰和可讀性。
  2. 當你的場景是簡單的“二選一”時

    • 首選:在JSX中直接使用三元運算符 ? :,代碼會非常簡潔優雅。
  3. 當你的場景是“有或無”的切換時

    • 首選:使用邏輯與 && 運算符,這是最簡便的方式。但要警惕左側表達式為0的陷阱。
  4. 當條件渲染邏輯本身變得復雜和龐大時

    • 首選:將這部分邏輯抽取并封裝到一個新的組件中,讓父組件保持清爽。

掌握了條件渲染,你就擁有了讓你的React應用“看情況辦事”的能力。這是構建任何有意義的交互式應用都不可或缺的一環。

在下一篇文章中,我們將繼續深入UI構建的另一個核心主題:列表渲染。我們將學習如何高效地將一個數組數據,渲染成一個漂亮的列表,并徹底搞懂那個神秘而又至關重要的key屬性到底是什么。

我是碼力無邊,為你的每一次進步點贊!記得動手練習今天學到的各種條件渲染技巧,試著在你之前的Todo List項目中加入一些“智能”判斷吧!我們下期再見!

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

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

相關文章

ubuntu掛載外接硬盤

查看找到硬盤sudo fdisk -l例如&#xff1a;名字為&#xff1a;/dev/sda創建掛載點sudo mkdir -p /2TSSD手動掛載&#xff08;單次生效&#xff0c;關機會失效&#xff09;sudo mount /dev/sda1 /2TSSD開機自動掛載&#xff08;永遠生效&#xff0c;關機會失效&#xff09;S1&a…

數學思想 | 數學思維過程對象封裝

注&#xff1a;本文為 “數學思維過程對象封裝” 相關譯文。 英文引文&#xff0c;機翻未校。 略作重排&#xff0c;如有內容異常&#xff0c;請看原文。 What is the object of the encapsulation of a process? 過程封裝的對象是什么&#xff1f; David Tall#, Michael Th…

常見視頻封裝格式對比

一、核心概念&#xff1a;封裝格式 vs 編碼格式 編碼格式 (Codec): 例如 H.264, H.265 (HEVC), AV1, VP9。它負責對原始視頻和音頻數據進行壓縮&#xff0c;是決定視頻體積和清晰度的關鍵。封裝格式 (Container): 例如 MP4, MKV, AVI。它負責將已經壓縮好的視頻、音頻、字幕等打…

Java實現PDF表格轉換為CSV

在很多企業辦公和數據分析的場景中&#xff0c;PDF 中常常存放著報表、清單或統計數據。相比 PDF&#xff0c;CSV 文件 更易于在 Excel 或數據庫中進行進一步處理。因此&#xff0c;我們常常需要一種方式&#xff0c;將 PDF 中的表格數據批量抽取并導出為 CSV 文件。 本文將介…

具有類人先驗知識的 Affordance-覺察機器人靈巧抓取

25年8月來自武漢大學、阿里達摩院、湖畔研究中心、浙大和清華的論文“Towards Affordance-Aware Robotic Dexterous Grasping with Human-like Priors”。 能夠泛化抓取目標的靈巧手是開發通用具身人工智能的基礎。然而&#xff0c;之前的方法僅僅關注低級抓取穩定性指標&#…

項目管理的關鍵成功因素

項目管理的關鍵成功因素包括&#xff1a;目標明確、科學規劃、有效溝通、資源保障、風險管理、團隊協作、持續監控與總結改進。目標明確保證方向不偏移、科學規劃確保執行有章可循、有效溝通減少誤解與沖突、資源保障提供堅實支撐、風險管理幫助預防問題、團隊協作提升整體效率…

[光學原理與應用-338]:ZEMAX - Documents\Zemax\Samples

Documents\Zemax\Samples 是 Zemax OpticStudio 軟件自帶的樣例文件目錄&#xff0c;包含大量預設的光學設計案例&#xff0c;涵蓋鏡頭設計、照明系統、公差分析、非序列光學等多個領域。這些樣例是學習軟件功能、驗證設計方法和快速啟動項目的寶貴資源。以下是該目錄的詳細解析…

el-table合并列實例

想要實現效果&#xff1a;目前接口返回數據data:[{companyCode: "NXKYS",companyName:1123,costContractId:1123,costContractName:1123,createBy:1123,details:[{brand:1123,contractItemName:1123,modelSpec:1123,projectItemId:1123,requestQty:1123,transactionZ…

虛假 TradingView Facebook 廣告在全球傳播 Android 間諜軟件

一項快速發展的惡意廣告活動最初通過 Meta 的廣告網絡針對 Windows 用戶&#xff0c;現已將其范圍擴展到 Android 設備&#xff0c;推廣偽裝成合法交易應用程序的 Brokewell 惡意軟件的高級版本。 Bitdefender Labs 警告稱&#xff0c;此次移動攻擊活動目前已在全球范圍內展開…

Android系統框架知識系列(十九):Android安全架構深度剖析 - 從內核到應用的全棧防護

?關鍵詞?&#xff1a;安全啟動鏈、應用沙箱、SELinux、硬件安全模塊、權限控制、零信任架構一、Android安全架構的基本概念與背景1. 移動安全環境的特殊性Android作為全球最大的移動操作系統&#xff0c;面臨著獨特的安全挑戰&#xff1a;?移動設備的安全威脅維度?&#xf…

智能消防栓悶蓋終端:讓城市消防管理更智慧高效

然而您是否知道&#xff0c;這些傳統的消防栓常常面臨非法開啟、人為破壞、水壓不足等管理難題&#xff1f;當火災真正發生時&#xff0c;它們能否可靠地提供"救命水"&#xff1f;如今&#xff0c;隨著智能消防栓悶蓋終端的出現&#xff0c;這一切正在悄然改變。 智…

【系統架構設計(一)】系統工程與信息系統基礎上:系統工程基礎概念

文章目錄一、系統工程的基本概念二、系統工程方法論1、霍爾三維結構&#xff1a;硬科學2、切克蘭德方法&#xff1a;軟科學思維3、其他三、系統工程生命周期管理1、生命周期階段劃分2、生命周期方法論系統工程與信息系統基礎為復雜系統設計提供從思維方法到具體技術的全方位指導…

[p2p-Magnet] 隊列與處理器 | DHT路由表

第6章&#xff1a;隊列與處理器 在第5章&#xff1a;分類器中&#xff0c;我們了解了系統如何分析原始種子數據。但當系統突然發現數百萬新種子時&#xff0c;如何高效處理這些海量任務&#xff1f;這就是隊列與處理器系統的職責所在。 核心概念 任務隊列 功能定位&#xf…

Spring JDBC 源碼初探:異常處理體系

一、Spring JDBC 異常體系簡介 當我們使用 Spring JDBC 進行數據訪問時&#xff0c;大多數人關注的是 JdbcTemplate 如何簡化數據庫操作&#xff0c;卻很少有人去深入理解異常體系。事實上&#xff0c;異常不僅僅是錯誤提示&#xff0c;它是系統健壯性、可維護性的重要一環。JD…

如何提高微型導軌的生產效率?

在精密機械制造領域&#xff0c;每一個細微的元件都可能成為決定產品性能和品質的關鍵因素。而微型導軌正是體型小、高精度優勢&#xff0c;在精密制造領域得到廣泛應用&#xff0c;它高效支撐著現代工業的生產方式和效率。那么&#xff0c;如何提高微型導軌的生產效率呢&#…

輕量xlsx讀取庫xlsx_drone的編譯與測試

這個庫是在看其他網頁時&#xff0c;作為和功能豐富的xlsxio庫的對比來的&#xff0c;按照xlsx_drone github頁面介紹&#xff0c; 特征 不使用任何外部應用程序來解析它們。注重速度而不是功能。簡單的接口。UTF-8 支持。 安裝 直接將 src 和 ext 文件夾復制并粘貼到項目根文…

Linux/UNIX系統編程手冊筆記:文件I/O、進程和內存分配

文件 I/O 深度解析&#xff1a;掌握通用 I/O 模型的核心邏輯 在 Linux 系統編程中&#xff0c;文件 I/O 是程序與外部設備&#xff08;文件、設備等 &#xff09;交互的基礎。從打開文件到讀寫數據&#xff0c;再到關閉資源&#xff0c;一系列系統調用構成了通用 I/O 模型的核心…

C++轉置正方形矩陣

C轉置正方形矩陣&#xff0c;就是正方形矩陣的a[i][j]a[j][i]。輸入31 2 34 5 6 7 8 9輸出1 4 72 5 83 6 9#include<bits/stdc.h> using namespace std; int main(){int n;cin>>n;int arr[n5][n5];for(int i0;i<n;i){for(int j0;j<n;j){cin>>arr[i][j]…

Ztero文獻管理工具插件設置——親測有效

一、Zotero簡介與安裝 Zotero是一款開源文獻管理軟件&#xff0c;能夠幫助我們方便地收集、整理、引用和導出文獻。它作為一個"在你的網頁瀏覽器中工作的個人研究助手"&#xff0c;可以捕獲網頁內容并自動添加引用信息。 安裝步驟&#xff1a; 訪問Zotero官網&…

【gflags】安裝與使用

gflags1. 介紹2. 安裝3. 使用3.1 頭文件3.2 定義參數3.3 訪問參數3.4 不同文件訪問參數3.5 初始化所有參數3.6 運行參數設置3.7 配置文件的使用3.8 特殊參數標識1. 介紹 gflags 是 Google 開發的一個開源庫&#xff0c;用于 C 應用程序中命令行參數的聲明、定義和解析。gflags…