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

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

藉助React,咱們能夠構建動態且高度交互的單頁應用程序,充分利用這種交互性的一種方法是經過條件渲染css

目錄

條件渲染一詞描述了根據某些條件渲染不一樣UI標籤的能力。在React文檔中,這是一種根據條件渲染不一樣元素或組件的方法。此概念一般被應用到以下狀況中:html

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

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

挑戰

首先,根據在組件state中isLoggedIn的值,咱們但願可以在用戶未登入時顯示Login按鈕,在用戶登入時顯示Logout按鈕。react

下圖是咱們初始組件的截圖:
git

代碼以下:github

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數組

解決方法

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

1. 使用if…else語句

使用if…else語句容許咱們能夠指出,若是條件爲true,則執行特定的操做,不然將執行其餘操做。使用示例,我將測試if…else一般用於在React中條件渲染的兩種方法。dom

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

在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語句提取成函數或提取成純函數組件

可是,這些僅是建議,最終仍是根據實際狀況選擇。

相關文章
相關標籤/搜索