【譯】在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
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...