【譯】在React中實現條件渲染的7種方法

来源:https://www.cnblogs.com/hanksyao/archive/2019/12/20/12066412.html
-Advertisement-
Play Games

藉助React,我們可以構建動態且高度交互的單頁應用程式,充分利用這種交互性的一種方法是通過條件渲染。 ...


原文地址:https://scotch.io/tutorials/7-ways-to-implement-conditional-rendering-in-react-applications

藉助React,我們可以構建動態且高度交互的單頁應用程式,充分利用這種交互性的一種方法是通過條件渲染

目錄

條件渲染一詞描述了根據某些條件渲染不同UI標簽的能力。在React文檔中,這是一種根據條件渲染不同元素或組件的方法。此概念通常被應用到如下情況中:

  • 從API渲染外部數據
  • 顯示/隱藏元素
  • 切換應用程式功能
  • 實現許可權級別
  • 認證與授權

在本文中,我們將研究在React應用程式中實現條件渲染的7種方法。

挑戰

首先,根據在組件state中isLoggedIn的值,我們希望能夠在用戶未登入時顯示Login按鈕,在用戶登入時顯示Logout按鈕。

下圖是我們初始組件的截圖:

代碼如下:

import React, { Component } from "react";
import ReactDOM from "react-dom";
import "./styles.css";

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      isLoggedIn: true
    };
  }
  render() {
    return (
      <div className="App">
        <h1>
          This is a Demo showing several ways to implement Conditional Rendering in React.
        </h1>
        <button>Login</button>
        <button>Logout</button>
      </div>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

線上測試:CodeSandBox

解決方法

在代碼段中,…表示某些與所解釋要點沒有直接聯繫的代碼。

1. 使用if…else語句

使用if…else語句允許我們可以指出,如果條件為true,則執行特定的操作,否則將執行其他操作。使用示例,我將測試if…else通常用於在React中條件渲染的兩種方法。

  • 將條件渲染提取到函數中

在JSX中,我們可以將JS代碼和HTML標簽放在一起,以確保程式內具有驚人的交互性。為此,我們使用大括弧{}併在其中編寫我們的JS。但在括弧內能做事情也是有限的。例如,下麵代碼的結果並不能實現我們想要的結果。

// index.js
...
render() {
  let {isLoggedIn} = this.state;
  return (
    <div className="App">
      <h1>
        This is a Demo showing several ways to implement Conditional Rendering in React.
      </h1>
      {
        if(isLoggedIn){
          return <button>Logout</button>
        } else{
          return <button>Login</button>
        }
      }
    </div>
  );
}
...

要瞭解更多相關信息,請訪問此鏈接

為瞭解決這個問題,我們將條件邏輯提取到一個函數中,如下所示:

// index.js
...
render() {
  let {isLoggedIn} = this.state;
  const renderAuthButton = ()=>{
    if(isLoggedIn){
      return <button>Logout</button>
    } else{
      return <button>Login</button>
    }
  }
  return (
    <div className="App">
      <h1>
        This is a Demo showing several ways to implement Conditional Rendering
        in React.
      </h1>
      {renderAuthButton()}
    </div>
  );
}
...

註意,我們將邏輯從JSX提取到函數renderAuthButton中。因此,我們只需要在JSX大括弧內執行函數即可。

  • 多個返回語句

在使用此方法時,組件必須儘可能的簡單,以避免兄弟或父組件的重新渲染。因此,我們創建了一個名為AuthButton的新組件。

// AuthButton.js

import React from "react";

const AuthButton = props => {
  let { isLoggedIn } = props;
  if (isLoggedIn) {
    return <button>Logout</button>;
  } else {
    return <button>Login</button>;
  }
};
export default AuthButton;

AuthButton根據通過組件屬性isLoggedIn傳入的狀態值,返回不同的元素和組件。因此,我們將其導入index.js並將狀態值傳入,如下所示:

// index.js
...
import AuthButton from "./AuthButton";

...
  render() {
    let { isLoggedIn } = this.state;
    return (
      <div className="App">
      ...
        <AuthButton isLoggedIn={isLoggedIn} />
      </div>
    );
  }
...

一定要避免下麵的操作:

// index.js
...
render() {
  let { isLoggedIn } = this.state;
  if (isLoggedIn) {
    return (
      <div className="App">
        <h1>
          This is a Demo showing several ways to implement Conditional
          Rendering in React.
        </h1>
        <button>Logout</button>;
      </div>
    );
  } else {
    return (
      <div className="App">
        <h1>
          This is a Demo showing several ways to implement Conditional
          Rendering in React.
        </h1>
        <button>Login</button>
      </div>
    );
  }
}
...

雖然上述代碼將實現相同的結果,但使得組件不必要的臃腫,同時由於不斷重新渲染一個不變的組件而導致性能問題。

2. 使用元素變數

元素變數是上述的將條件渲染提取到函數中的一個擴展。元素變數只是保存JSX元素的變數。因此,我們可以在JSX外部根據條件將元素/組件賦值給這些變數,僅在JSX渲染變數即可。

// index.js
...
render() {
  let { isLoggedIn } = this.state;
  let AuthButton;
  if (isLoggedIn) {
    AuthButton = <button>Logout</button>;
  } else {
    AuthButton = <button>Login</button>;
  }
  return (
    <div className="App">
      <h1>
        This is a Demo showing several ways to implement Conditional Rendering in React.
      </h1>
      {AuthButton}
    </div>
  );
}
...

註意我們如何有條件地將值(組件)分配給AuthButton,然後我們只需要在JSX中渲染它即可。

3. 使用switch語句

如前所示,我們可以使用if…else語句根據設置的條件從組件返回不同的標簽。使用switch語句也可以達到相同的效果,在該語句中我們可以為不同的條件指定標簽。看看如下代碼:

// AuthButton.js
import React from "react";

const AuthButton = props => {
  let { isLoggedIn } = props;
  switch (isLoggedIn) {
    case true:
      return <button>Logout</button>;
      break;
    case false:
      return <button>Login</button>;
      break;
    default:
      return null;
  }
};

export default AuthButton;

註意我們如何根據isLoggedIn的值返回不同的按鈕。當存在兩個以上可能的值或結果時,採用此方法更為合理。你也可以通過break語句取消,正如return語句自動終止執行一樣。

註意:從組件返回null會使它隱藏自身/不顯示任何內容。這是切換組件可見性的好方法。

4. 三元運算符

如果你熟悉三元運算符,那麼你應該知道這是編寫if語句的一種更簡潔的方法。因此我們也許會這樣寫:

// index.js
...
render() {
  let { isLoggedIn } = this.state;
  return (
    <div className="App">
      <h1>
        This is a Demo showing several ways to implement Conditional Rendering
        in React.
      </h1>
      {isLoggedIn ? <button>Logout</button> : <button>Login</button>}
    </div>
  );
}
...

但在上例中,這種方法會使組件臃腫,笨重和難以理解,你可以將條件封裝在純函數組件中。如下所示:

// AuthButton.js
import React from "react";

const AuthButton = props => {
  let { isLoggedIn } = props;
  return isLoggedIn ? <button>Logout</button> : <button>Login</button>;
};

export default AuthButton;

5. 邏輯運算符&&

短路運算是一種用於確保在表達式運算過程中沒有副作用的技術。邏輯&&幫助我們指定僅在一種情況下執行,否則將被完全忽略。這對於僅在特定條件為真時才需要執行的情況下是很有用的。

例如,如果是登錄狀態,我們只需顯示Logout按鈕,否則我們什麼也不做。如下:

// index.js
...
render() {
  let { isLoggedIn } = this.state;
  return (
    <div className="App">
      <h1>
        This is a Demo showing several ways to implement Conditional Rendering
        in React.
      </h1>
      {isLoggedIn && <button>Logout</button>}
    </div>
  );
}
...

如果isLoggedIn為true,則將顯示Logout按鈕,否則將不顯示任何內容。我們用相同方法就可以實現最終結果,如下所示。

// index.js
...
return (
  <div className="App">
    <h1>
      This is a Demo showing several ways to implement Conditional Rendering
      in React.
    </h1>
    {isLoggedIn && <button>Logout</button>}
    {!isLoggedIn && <button>Login</button>}
  </div>
);
...

這是基於isLoggedIn的值渲染正確的按鈕。但是,不建議這樣做,因為有更好、更清潔的方法可以達到相同的效果。而且,一旦組件稍大一些,這很容易使你代碼看起來混亂和難以理解。

6. 使用立即調用函數表達式(IIFE)

還記的剛纔說的JSX局限性嗎,在其中無法執行所有JavaScript代碼。嗯...這並不完全正確的,因為有很多方法可以繞過這種行為。一種方法是使用IIFE。

(function () {
  statements
})();

點擊鏈接瞭解更多

通過這種技術,我們能夠直接在JSX內編寫條件邏輯,但將其包裝在匿名函數中,該匿名函數在運行該部分代碼後立即被調用。請參見下麵的示例:

//index.js
...
render() {
  let { isLoggedIn } = this.state;
  return (
    <div className="App">
      <h1>
        This is a Demo showing several ways to implement Conditional Rendering
        in React.
      </h1>
      {(function() {
        if (isLoggedIn) {
          return <button>Logout</button>;
        } else {
          return <button>Login</button>;
        }
      })()}
    </div>
  );
}
...

也可以使用箭頭功能,通過更加簡潔的方式編寫該代碼,如下所示:

// index.js
...
return (
  <div className="App">
    <h1>
      This is a Demo showing several ways to implement Conditional Rendering in React.
    </h1>
    {(()=> {
      if (isLoggedIn) {
        return <button>Logout</button>;
      } else {
        return <button>Login</button>;
      }
    })()}
  </div>
);
...

7. 使用增強的JSX

某些庫公開了擴展JSX的功能,因此可以直接用JSX實現條件渲染。此類庫之一是JSX Control Statements。它是Babel插件,可在編譯過程中將類似組件的控制語句轉換為JavaScript對應的語句。請參閱下麵的示例以瞭解如何實現。

// index.js
...
return (
  <div className="App">
    <h1>
      This is a Demo showing several ways to implement Conditional Rendering in React.
    </h1>
    <Choose>
      <When condition={isLoggedIn}>
         <button>Logout</button>;
      </When>
      <When condition={!isLoggedIn}>
         <button>Login</button>;
      </When>
    </Choose>
  </div>
);
...

但是,不建議使用這種方法,因為您編寫的代碼最終會轉換為常規JavaScript條件。僅僅編寫JavaScript可能總比對如此瑣碎的事情增加額外的依賴要好。

性能問題

作為通用規則,最好確保在實現條件渲染時:

  • 請勿隨意更改組件的位置,以防止不必要地卸卸和重載組件。
  • 僅更改與條件渲染有關的標簽,而不改變組件中沒有變動的部分。
  • 不要在render方法中使組件不必要的臃腫,從而導致組件延遲渲染。

總結

我們已經成功研究了在React中實現條件渲染的7種方法。每種方法都有其自身的優勢,選擇哪種方法主要取決於實際情況。要考慮的事項包括:

  • 條件渲染標簽的大小
  • 可能結果的數目
  • 哪個會更直觀和可讀

通常,我建議:

  • 當只有一個預期的結果時,使用邏輯&&運算符非常方便。
  • 對於布爾型情況或只有兩個可能結果的用例,可以使用if…elseElement變數三元運算符IIFE
  • 如果結果超過2個,則可以使用Switch語句提取成函數或提取成純函數組件

但是,這些僅是建議,最終還是根據實際情況選擇。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • XML 什麼是XML - Tomcat - Http XML:eXtensible Markup Language (可擴展標記語言)。 XML 是一種標記語言,很類似 HTML。 XML 的設計宗旨是傳輸數據,而非顯示數據。 XML的使命,就是以一個統一的格式,組織有關係的數據。為不同平臺下的應用 ...
  • 時間如流水,只能流去不流回! 點贊再看,養成習慣,這是您給我創作的動力! 本文 Dotnet9 https://dotnet9.com 已收錄,站長樂於分享dotnet相關技術,比如Winform、WPF、ASP.NET Core等,亦有C++桌面相關的Qt Quick和Qt Widgets等,只分 ...
  • 封裝了一個JS方法,支持元素的基本動畫:寬、高、透明度...等,也支持鏈式動畫和同時運動。 獲取元素的屬性的函數併進行了相容性處理: 1 function getStyle(obj, attr) { 2 if(obj.currentStyle){ //IE瀏覽器 3 return obj.curre ...
  • 入一行,要先知一行 ”;我們來看看web前端開發職位 無論什麼門派都要做到的一些基本工作職責 首先,你必須是一個合格的“頁面仔”,這個叫法不好聽,但很生動; 我們都知道,所有呈現的內容都是基於HTML 網頁的。 如果你的html、css(包括現在的HTML5+CSS3)基礎不會,或者不夠扎實,都很難 ...
  • web前端分享JavaScript到底是什麼?特點有哪些?這也是成為web前端工程師必學的內容。今天為大家分享了這篇關於JavaScript的文章,我們一起來看看。 一、JavaScript是什麼? 1、JavaScript是在網站瀏覽器上運行的編程語言。 主要是向使用HTML和CSS構建的網站添加 ...
  • 主要實現以下幾種簡單的動畫效果(其實原理基本相同): 1.勻速動畫:物體的速度固定 2.緩動動畫:物體速度逐漸變慢 3.多物體動畫 4.透明度動畫 效果實現: 1.勻速動畫(以物體左右勻速運動為例) 動畫效果主要是用定時器setInterval()來實現的,每隔幾毫秒讓物體移動一點距離,通過不斷調用 ...
  • 封裝緩動(變速)動畫函數 增加任意多個屬性&回調函數&層級&透明度 相較之前的,增加了2個判斷,第一個判斷是不是透明度,第二個判斷是不是zindex, 都不是,就只是普通屬性和之前一樣 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UT ...
  • 封裝緩動(變速)動畫函數 增加任意多個屬性&增加回調函數 回掉函數fn,在所有元素到達目的位置後,判斷是否傳入一個函數,有就調用 if(fn){fn()}; 這樣一次點擊,產生多個動畫 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UT ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...