React 條件渲染最佳實踐(7 種方法)

在 React 中,條件渲染能夠經過多種方式,不一樣的使用方式場景取決於不一樣的上下文。 在本文中,咱們將討論全部可用於爲 React 中的條件渲染編寫更好的代碼的方法。javascript

~~java

條件渲染在每種編程語言(包括 javascript)中都是的常見功能。 在 javascript 中,咱們一般使用if else 語句,switch case語句和三元運算符編寫條件渲染。react

以上全部這些方法都適用於 React。 可是問題是,咱們如何纔能有效地使用它們?git

像你知道的那樣,React 具備 JSX 標記,一般咱們須要實現條件邏輯去控制組件。 可是,咱們不能在 JSX 中直接使用常見的 if elseswitch case語句。程序員

在 JSX 中,咱們應該使用其餘條件渲染方法,例如三元運算符和&&運算符。 在這裏,咱們將討論更多細節。github

如下是我積累的 7 種條件渲染方法,它們能夠在 React 中使用。 每種方式在必定的狀況下都有本身的優點。編程

目錄微信

  • If Else條件渲染
  • 使用三元運算符進行條件渲染
  • &&運算符的條件渲染
  • switch case多條件渲染
  • 枚舉對象的多條件渲染
  • HOC(高階組件)條件渲染
  • 帶有外部庫的 JSX 條件渲染

1.If Else條件渲染

最佳實踐概述babel

  • 在 JSX 標記以外的任何地方使用
  • 或者,若是你想在 if-else 塊中執行多行代碼

~~編程語言

這是全部程序員都能想到的第一個方法,即常見的 if-else語句。 咱們能夠在 React 項目中的任何地方使用它。

在 React 中,若是要在 if 或者 else 塊內部或 JSX 外部的任何地方執行多行代碼,最好使用通用的 if-else 語句。

例如,若是用戶登陸,咱們想執行一些代碼。

// * Conditional rendering with common if-else statement.
if (isLoggedIn) {
  setUserProfile(userData);
  setUserHistory(userHistory);
  // other block of codes;
}

或者,當你想基於用戶角色定義可訪問的內容時。

if (userProfile.role === "superadmin") {
  initSuperAdminFunction();
  initSuperAdminComponent();
  // other block of codes;
} else if (userProfile.role === "admin") {
  initAdminFunction();
  initAdminComponent();
  // other block of codes;
} else {
  initUserComponent();
  // other block of codes;
}

若是你只想執行一行代碼,例如在 if 或 else 塊中調用函數,則能夠刪除括號。

if (userProfile.role === "superadmin") initSuperAdminComponent();
else if (userProfile.role === "admin") initAdminFunction();
else initUserComponent();

if-else 中不帶括號的條件僅適用於其正下方的一行代碼。

JSX 中的 if else 語句

你可能知道,咱們能夠在 JSX 中的方括號{}中注入和混合一些 javascript 代碼。 可是它有一些侷限性。

你不能直接向其中插入 if-else 語句。 在 JSX 中注入 if-else 語句僅適用於當即調用函數表達式(IIFE),以下所示:

return (
  <div>
    {(() => {
      if (isLoggedIn) {
        return <div>I'm logged in.</div>;
      }
    })()}
  </div>
);

如你所見,僅 if 語句就太冗長了。 這就是爲何我不建議在 JSX 中使用 if-else 語句的緣由。

繼續閱讀 JSX 中還有其餘一些條件渲染的方法。

  1. 使用三元運算符進行條件渲染

最佳實踐概覽

  • 條件變量或函數返回值賦值
  • 當你只想寫一行代碼來作條件判斷
  • 於 JSX 中的條件渲染

三元運算符是常見 if-else 語句的快捷方式。 使用三元運算符,你能夠在行內編寫條件渲染,也能夠只編寫一行代碼。

讓咱們看一下條件渲染的變量值分配示例。

// Conditional rendering with common if else
let isDrinkCoffee;
if (role === "programmer") {
  isDrinkCoffee = true;
} else {
  isDrinkCoffee = false;
}

// Conditional rendering with ternary operator
let isDrinkCoffee = role === "programmer" ? true : false;

這是函數返回值的條件渲染示例:

// Conditional rendering with common if else
function isDrinkCoffee(role) {
  if (role === "programmer") {
    return true;
  } else {
    return false;
  }
}

// Conditional rendering with ternary operator
function isDrinkCoffee(role) {
  return role === "programmer" ? true : false;
}

如你所見, 你用了三元運算符,就用用一行代碼來代替 if-else 語句。

你也能夠在 JSX 中使用三元運算符,而不是將 if-else 與當即調用函數表達式(IIFE)一塊兒使用。

假設咱們要基於 isShow 狀態有條件地渲染一個小組件。 您能夠這樣編寫條件渲染。

return <div>{isShow ? <SmallComponent /> : null}</div>;

if-else if-else使用三元運算符

在上面的示例中,我僅向你展現如何使用三元運算符替換 if-else 語句。

三元運算符還可用於替換多個條件渲染(if-else if-else)或嵌套的條件渲染。

可是,我不建議你使用它,由於它比普通的 if-else語句更難讀。

假設你要在 JSX 中實現嵌套的條件渲染。

return (
  <div>
    {condition_a ? (
      <ComponentA />
    ) : condition_b ? (
      <ComponentB />
    ) : condition_c ? (
      <ComponentC />
    ) : (
      <ComponentD />
    )}
  </div>
);

看起來很是亂,是吧?

對於這種狀況,使用 IIFE,switch-case 語句或枚舉對象比三元運算符更好。

3.&&運算符的條件渲染

最佳實踐概覽

  • 使用它進行簡單的條件渲染,沒必要去執行"else"塊中的代碼。

~~

使用三元運算符,能夠縮短 if-else 語句的代碼量,併爲 JSX 中的條件渲染提供更好的選擇。

可是,你知道有比三元運算符更簡單的方法嗎?

&&運算符可用於替換此類 if 語句。

// Instead of using ternary operator,
{
  isShow ? <SmallComponent /> : null;
}

// Use short-circuit && operator
{
  isShow && <SmallComponent />;
}

在三元運算符中,即便沒有"else"條件,也須要寫"null"表達式以免語法錯誤。

使用&&運算符,你不須要寫多餘的代碼。

可是,請記住,不能將&&運算符替換爲if-else語句,更不用說if-else if-else語句了。

4.帶 switch 的多條件渲染-案例

  • 能夠在任何位置使用它來進行多個條件渲染,而只有一個變量能夠判斷條件。

~~

if-else語句同樣,switch-case語句也是幾乎每種編程語言中的常見功能。

它用於具備相同類型條件的多個條件渲染。

例如,咱們可使用switch-case語句根據用戶角色呈現特定的變量值。

let welcomeMessage;
switch (role) {
  case "superadmin":
    welcomeMessage = "Welcome Super Admin";
  // you can put other codes here as well.
  case "admin":
    welcomeMessage = "Welcome Admin";
  // you can put other codes here as well.
  case "user":
    welcomeMessage = "Welcome User";
  // you can put other codes here as well.
  default:
    welcomeMessage = "Welcome Guest";
  // you can put other codes here as well.
}

你還可使用switch-case語句在 JSX 中進行條件渲染。 可是,你須要將其包裝在 IIFE 中。

假設你要呈現一個基於 alert 狀態設置樣式的alert組件。

return (
  <div>
    {(() => {
      switch (status) {
        case "warning":
          return <AlertComponent status="warning" message={messageState} />;
        case "error":
          return <AlertComponent status="error" message={messageState} />;
        case "success":
          return <AlertComponent status="success" message={messageState} />;
        default:
          return <AlertComponent status="info" message={messageState} />;
      }
    })()}
  </div>
);

你可能已經注意到,兩個示例都只有一個變量(rolestatus)來判斷條件。 這就是我以前所說的相同類型的條件。

switch-case語句不能用於處理複雜和不一樣類型的條件。可是你可使用通用的if-else if-else語句去處理那些場景。

5.枚舉對象的多重條件渲染

  • 僅當您要分配具備多個條件的變量值或返回值時,才使用它。

~~

枚舉對象還能夠用於在 React 中實現多個條件渲染。 對於 JSX 標記中的 switch-case語句,它是更好的選擇。

如你所知,在第 5 種方法中,你應該將switch-case語句包裝在 JSX 的 IIFE 中。 使用枚舉對象,你不須要這樣作。

讓咱們用一個之前的一個示例來距離。 你要基於狀態呈現 alert 組件。 這是使用枚舉對象有條件地呈現它的方式。

const ALERT_STATUS = {
  warning: <AlertComponent status="warning" />,
  error: <AlertComponent status="error" />,
  success: <AlertComponent status="success" />,
  info: <AlertComponent status="info" />,
};

return <div>{ALERT_STATUS[status]}</div>;

你須要建立一個枚舉對象,首先稱爲「 ALERT_STATUS」。 而後,只需在 JSX 中使用 []括號內的狀態變量來調用它,該變量的值爲'warning','error','success'或'info'。

若是須要傳遞其餘道具或屬性,則能夠將 ALERT_STATUS 更改成這樣的函數。

const ALERT_STATUS = (message) => ({
  warning: <AlertComponent status="warning" message={message} />,
  error: <AlertComponent status="error" message={message} />,
  success: <AlertComponent status="success" message={message} />,
  info: <AlertComponent status="info" message={message} />,
});

return <div>{ALERT_STATUS(messageState)[status]}</div>;

你還能夠將變量傳遞給 alert 組件。

let newVariable = ALERT_STATUS(messageState)[status];

固然,你應該首先定義枚舉對象。

將枚舉對象拆分到單獨文件來複用

關於使用枚舉對象進行條件渲染的最好的特性是能夠複用。

回到示例案例,Alert 組件是 React 中一般可重用的組件。 所以,當你要有條件地渲染它時,也可讓它複用。

你能夠在單獨的文件中定義枚舉,而後將它導出。

import React from "react";
import AlertComponent from "./path/to/AlertComponent";

export const ALERT_STATUS = (message) => ({
  warning: <AlertComponent status="warning" message={message} />,
  error: <AlertComponent status="error" message={message} />,
  success: <AlertComponent status="success" message={message} />,
  info: <AlertComponent status="info" message={message} />,
});

而後,在要在組件中使用它時將其導入。

import { ALERT_STATUS } from "./alertStatus";

用法與之前相同。

6.HOC 條件渲染

最佳作法摘要

  • 若是要在渲染組件以前實現或檢查某些條件,請使用它。

~~

高階組件(HOC)可用於在 React 中實現條件渲染。 當你要運行某些邏輯或在渲染組件以前進行檢查時,可使用它。

例如,你要在訪問某些組件以前檢查用戶是否已經過身份驗證。

你可使用 HOC 來保護那些組件,而不是在每一個須要身份驗證的組件中編寫if-else語句。

// This is Higher Order Component
import React from "react";
export default function withAuthentication(Component) {
  // some code of authentication logic/service that result an isLoggedIn variable/state:
  let isLoggedIn = true;

  return function AuthenticatedComponent(props) {
    if (isLoggedIn) {
      return <Component {...props} />;
    } else {
      return <div class="alert alert-danger">You're not authenticated!</div>;
    }
  };
}

而後,您能夠將其導入並在組件中使用。

import withAuthentication from "./withAuthentication";
const AuthenticatedUIComponent = withAuthentication(AnUIComponent);

return (
  <div>
    <AuthenticatedUIComponent />
  </div>
);

這樣更棒了,是嗎?

你能夠將 HOC 用於其餘可複用的條件渲染,例如加載指示器實現空值檢查 等。

有關 HOC(具備功能組件)的更多詳細信息,能夠在 medium (https://medium.com/@albertchu539/higher-order-components-in-a-react-hooks-world-69fe1f0b0791)。

7.帶有外部庫的 JSX 條件渲染

最佳作法摘要

  • 避免使用此方法。 熟悉上面的 6 種方法:D

儘管我不建議你使用此方法,但我只是想讓你知道,有一個 babel 插件使 JSX 具備本身的條件渲染標記。

使用 JSX 控制語句,您能夠像這樣在 JSX 中編寫條件渲染。

<If condition={test}>
  <span>Truth</span>
</If>;

<Choose>
  <When condition={test1}>
    <span>IfBlock</span>
  </When>
  <When condition={test2}>
    <span>ElseIfBlock</span>
    <span>Another ElseIfBlock</span>
    <span>...</span>
  </When>
  <Otherwise>
    <span>ElseBlock</span>
  </Otherwise>
</Choose>;

在編譯中,這些標籤將轉換爲三元運算符。

一些開發人員使用此插件,由於它對於 JSX 中的條件渲染看起來更具可讀性。

~~

譯者注: 你還能夠實現一個簡單的 IF 組件來實現簡單的判斷。

const If = (props) => {
  const condition = props.condition || false;
  const positive = props.then || null;
  const negative = props.else || null;

  return condition ? positive : negative;
};
<IF condition={isLoggedIn} then={<Hello />} else={<div>請先登陸</div>} />

這就是你能夠在 React 中用於條件渲染的全部 7 種方法。

編碼愉快!

譯文來自 https://dev.to/syakirurahman/react-conditional-rendering-best-practices-with-7-different-methods-16e3#6_Conditional_Rendering_with_HOC

原做者 Syakir Rahman

譯者: 藍色的秋風(github/hua1995116)

最後

若是個人文章有幫助到你,但願你也能幫助我,歡迎關注個人微信公衆號 秋風的筆記,回覆好友 二字,可加微信而且加入交流羣,秋風的筆記 將一直陪伴你的左右。

也能夠掃碼加我微信好友,進交流羣。

相關文章
相關標籤/搜索