你的元件通常需要根據不同的條件顯示不同的內容。在 React 中,你可以使用 JavaScript 語法(例如 if 陳述式、&& 和 ? : 運算子)來條件式渲染 JSX。
你將會學到
- 如何根據條件返回不同的 JSX
- 如何有條件地包含或排除一段 JSX
- 在 React 程式碼庫中常見的條件語法捷徑
條件式返回 JSX
假設你有一個 PackingList 元件渲染多個 Item,這些項目可以標記為已打包或未打包
function Item({ name, isPacked }) { return <li className="item">{name}</li>; } export default function PackingList() { return ( <section> <h1>Sally Ride's Packing List</h1> <ul> <Item isPacked={true} name="Space suit" /> <Item isPacked={true} name="Helmet with a golden leaf" /> <Item isPacked={false} name="Photo of Tam" /> </ul> </section> ); }
請注意,某些 Item 元件的 isPacked prop 設定為 true 而不是 false。如果 isPacked={true},你想要在已打包的項目上新增一個核取記號 (✅)。
你可以將它寫成 if/else 陳述式,如下所示
if (isPacked) {
return <li className="item">{name} ✅</li>;
}
return <li className="item">{name}</li>;如果 isPacked prop 為 true,則此程式碼會**返回不同的 JSX 樹狀結構。** 經過此更改後,某些項目末尾會出現核取記號
function Item({ name, isPacked }) { if (isPacked) { return <li className="item">{name} ✅</li>; } return <li className="item">{name}</li>; } export default function PackingList() { return ( <section> <h1>Sally Ride's Packing List</h1> <ul> <Item isPacked={true} name="Space suit" /> <Item isPacked={true} name="Helmet with a golden leaf" /> <Item isPacked={false} name="Photo of Tam" /> </ul> </section> ); }
試著編輯在任一情況下返回的內容,看看結果如何變化!
請注意,你如何使用 JavaScript 的 if 和 return 陳述式來建立分支邏輯。在 React 中,控制流程(例如條件)是由 JavaScript 處理的。
使用 null 有條件地不返回任何內容
在某些情況下,你根本不想渲染任何內容。例如,假設你根本不想顯示已打包的項目。元件必須返回某些內容。在這種情況下,你可以返回 null
if (isPacked) {
return null;
}
return <li className="item">{name}</li>;如果 isPacked 為 true,則元件將不返回任何內容,null。否則,它將返回要渲染的 JSX。
function Item({ name, isPacked }) { if (isPacked) { return null; } return <li className="item">{name}</li>; } export default function PackingList() { return ( <section> <h1>Sally Ride's Packing List</h1> <ul> <Item isPacked={true} name="Space suit" /> <Item isPacked={true} name="Helmet with a golden leaf" /> <Item isPacked={false} name="Photo of Tam" /> </ul> </section> ); }
實際上,從元件返回 null 並不常見,因為這可能會讓嘗試渲染它的開發人員感到驚訝。更常見的情況是,你會在父元件的 JSX 中有條件地包含或排除該元件。以下是執行此操作的方法!
條件式包含 JSX
在前面的範例中,你控制了元件將返回哪個(如果有的話!)JSX 樹狀結構。你可能已經注意到渲染輸出中的一些重複
<li className="item">{name} ✅</li>非常類似於
<li className="item">{name}</li>兩個條件分支都會返回 <li className="item">...</li>
if (isPacked) {
return <li className="item">{name} ✅</li>;
}
return <li className="item">{name}</li>;雖然這種重複無害,但它可能會使你的程式碼更難維護。如果你想更改 className 呢?你必須在程式碼中的兩個地方進行更改!在這種情況下,你可以有條件地包含一些 JSX 來使你的程式碼更 DRY(不要重複自己)。
條件(三元)運算符 (? :)
JavaScript 有一個用於編寫條件表達式的簡潔語法 — 稱為 條件運算符 或「三元運算符」。
取代以下寫法
if (isPacked) {
return <li className="item">{name} ✅</li>;
}
return <li className="item">{name}</li>;你可以這樣寫
return (
<li className="item">
{isPacked ? name + ' ✅' : name}
</li>
);你可以將其理解為 *「如果 isPacked 為 true,則(?)渲染 name + ' ✅',否則(:)渲染 name」*。
深入探討
如果你有物件導向程式設計的背景,你可能會認為上述兩個例子略有不同,因為其中一個例子可能會建立兩個不同的 <li>「實例」。但 JSX 元素不是「實例」,因為它們不持有任何內部狀態,也不是真正的 DOM 節點。它們是輕量級的描述,就像藍圖一樣。所以這兩個例子實際上是*完全相等的*。保存和重置狀態 詳細說明了這是如何運作的。
現在假設你想將已完成項目的文字包裝到另一個 HTML 標籤中,例如 <del> 來將其刪除線。你可以新增更多換行符和括號,以便更容易在每種情況下巢狀更多 JSX
function Item({ name, isPacked }) { return ( <li className="item"> {isPacked ? ( <del> {name + ' ✅'} </del> ) : ( name )} </li> ); } export default function PackingList() { return ( <section> <h1>Sally Ride's Packing List</h1> <ul> <Item isPacked={true} name="Space suit" /> <Item isPacked={true} name="Helmet with a golden leaf" /> <Item isPacked={false} name="Photo of Tam" /> </ul> </section> ); }
這種樣式適用於簡單的條件,但請適量使用。如果你的元件因為過多巢狀的條件標記而變得混亂,請考慮提取子元件來清理程式碼。在 React 中,標記是你程式碼的一部分,因此你可以使用變數和函數等工具來整理複雜的表達式。
邏輯 AND 運算符 (&&)
你會遇到的另一個常見捷徑是 JavaScript 邏輯 AND (&&) 運算符。 在 React 元件中,當你想在條件為 true 時渲染一些 JSX,**否則不渲染任何東西時**,它經常出現。使用 &&,你可以有條件地僅在 isPacked 為 true 時才渲染核取記號
return (
<li className="item">
{name} {isPacked && '✅'}
</li>
);你可以將其理解為 *「如果 isPacked,則(&&) 渲染核取記號,否則,不渲染任何東西」*。
實際應用如下
function Item({ name, isPacked }) { return ( <li className="item"> {name} {isPacked && '✅'} </li> ); } export default function PackingList() { return ( <section> <h1>Sally Ride's Packing List</h1> <ul> <Item isPacked={true} name="Space suit" /> <Item isPacked={true} name="Helmet with a golden leaf" /> <Item isPacked={false} name="Photo of Tam" /> </ul> </section> ); }
JavaScript && 表達式 如果左側(我們的條件)為 true,則返回其右側的值(在我們的例子中為核取記號)。但如果條件為 false,則整個表達式變為 false。React 將 false 視為 JSX 樹中的「空洞」,就像 null 或 undefined 一樣,並且不會在其位置渲染任何東西。
有條件地將 JSX 分配給變數
當捷徑妨礙編寫簡潔的程式碼時,請嘗試使用 if 陳述式和變數。你可以重新分配使用 let 定義的變數,因此首先提供你要顯示的預設內容,即名稱
let itemContent = name;如果 isPacked 為 true,請使用 if 陳述式將 JSX 表達式重新分配給 itemContent
if (isPacked) {
itemContent = name + " ✅";
}大括號開啟了「通往 JavaScript 的視窗」。 在返回的 JSX 樹中使用大括號嵌入變數,將先前計算的表達式嵌套在 JSX 內部
<li className="item">
{itemContent}
</li>這種風格最冗長,但也最靈活。以下是實際應用
function Item({ name, isPacked }) { let itemContent = name; if (isPacked) { itemContent = name + " ✅"; } return ( <li className="item"> {itemContent} </li> ); } export default function PackingList() { return ( <section> <h1>Sally Ride's Packing List</h1> <ul> <Item isPacked={true} name="Space suit" /> <Item isPacked={true} name="Helmet with a golden leaf" /> <Item isPacked={false} name="Photo of Tam" /> </ul> </section> ); }
和之前一樣,這不僅適用於文字,也適用於任意 JSX
function Item({ name, isPacked }) { let itemContent = name; if (isPacked) { itemContent = ( <del> {name + " ✅"} </del> ); } return ( <li className="item"> {itemContent} </li> ); } export default function PackingList() { return ( <section> <h1>Sally Ride's Packing List</h1> <ul> <Item isPacked={true} name="Space suit" /> <Item isPacked={true} name="Helmet with a golden leaf" /> <Item isPacked={false} name="Photo of Tam" /> </ul> </section> ); }
如果您不熟悉 JavaScript,一開始可能會覺得這些樣式令人不知所措。但是,學習它們將幫助您讀寫任何 JavaScript 程式碼,而不僅僅是 React 元件!首先選擇您喜歡的樣式,如果您忘記其他樣式如何運作,請再次參考此處。
重點回顧
- 在 React 中,您可以使用 JavaScript 控制分支邏輯。
- 您可以使用
if陳述式有條件地返回 JSX 表達式。 - 您可以有條件地將一些 JSX 儲存到變數中,然後使用大括號將其包含在其他 JSX 中。
- 在 JSX 中,
{cond ? <A /> : <B />}表示 *「如果cond,則渲染<A />,否則渲染<B />」*。 - 在 JSX 中,
{cond && <A />}表示 *「如果cond,則渲染<A />,否則不渲染任何內容」*。 - 這些捷徑很常見,但如果您喜歡普通的
if,則不必使用它們。
挑戰 1之 3: 使用 ? : 顯示未完成項目的圖示
如果 isPacked 不是 true,請使用條件運算子(cond ? a : b)來渲染 ❌。
function Item({ name, isPacked }) { return ( <li className="item"> {name} {isPacked && '✅'} </li> ); } export default function PackingList() { return ( <section> <h1>Sally Ride's Packing List</h1> <ul> <Item isPacked={true} name="Space suit" /> <Item isPacked={true} name="Helmet with a golden leaf" /> <Item isPacked={false} name="Photo of Tam" /> </ul> </section> ); }