在 React 中,條件渲染能夠經過多種方式,不一樣的使用方式場景取決於不一樣的上下文。 在本文中,咱們將討論全部可用於爲 React 中的條件渲染編寫更好的代碼的方法。javascript
~~java
條件渲染在每種編程語言(包括 javascript)中都是的常見功能。 在 javascript 中,咱們一般使用if else
語句,switch case
語句和三元運算符編寫條件渲染。react
以上全部這些方法都適用於 React。 可是問題是,咱們如何纔能有效地使用它們?git
像你知道的那樣,React 具備 JSX
標記,一般咱們須要實現條件邏輯去控制組件。 可是,咱們不能在 JSX
中直接使用常見的 if else
或switch case
語句。程序員
在 JSX 中,咱們應該使用其餘條件渲染方法,例如三元運算符和&&運算符。 在這裏,咱們將討論更多細節。github
如下是我積累的 7 種條件渲染方法,它們能夠在 React 中使用。 每種方式在必定的狀況下都有本身的優點。編程
目錄微信
If Else
條件渲染switch case
多條件渲染If Else
條件渲染最佳實踐概述babel
~~編程語言
這是全部程序員都能想到的第一個方法,即常見的 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 中還有其餘一些條件渲染的方法。
最佳實踐概覽
三元運算符是常見 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 語句或枚舉對象比三元運算符更好。
最佳實踐概覽
~~
使用三元運算符,能夠縮短 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
語句了。
~~
像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> );
你可能已經注意到,兩個示例都只有一個變量(role
和status
)來判斷條件。 這就是我以前所說的相同類型的條件。
switch-case
語句不能用於處理複雜和不一樣類型的條件。可是你可使用通用的if-else if-else
語句去處理那些場景。
~~
枚舉對象還能夠用於在 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";
用法與之前相同。
最佳作法摘要
~~
高階組件(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)。
最佳作法摘要
儘管我不建議你使用此方法,但我只是想讓你知道,有一個 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)
若是個人文章有幫助到你,但願你也能幫助我,歡迎關注個人微信公衆號 秋風的筆記
,回覆好友
二字,可加微信而且加入交流羣,秋風的筆記
將一直陪伴你的左右。
也能夠掃碼加我微信好友,進交流羣。