React 條件渲染 (Conditional Rendering)
在 React 中,你可以根據不同的條件來渲染不同的 UI。這就是所謂的條件渲染,有幾種常見的寫法可以達成這個目的。
JavaScript if else
最直接的方式就是使用 JavaScript 的 if else 語法:
function Greeting({ isLoggedIn }) {
if (isLoggedIn) {
return <h1>歡迎回來!</h1>;
}
return <h1>請先登入</h1>;
}
// 使用
<Greeting isLoggedIn={true} /> // 顯示「歡迎回來!」
<Greeting isLoggedIn={false} /> // 顯示「請先登入」
這種方式適合在需要根據條件回傳完全不同的 JSX 結構時使用。
三元運算子 ? :
三元運算子(Conditional Ternary Operator)是最常用的條件渲染方式,因為它可以直接寫在 JSX 中:
function Greeting({ isLoggedIn }) {
return <h1>{isLoggedIn ? '歡迎回來!' : '請先登入'}</h1>
}
語法:
{
條件 ? 條件為真時的內容 : 條件為假時的內容
}
三元運算子也可以用來渲染不同的元件:
function UserPanel({ isLoggedIn }) {
return <div>{isLoggedIn ? <UserDashboard /> : <LoginForm />}</div>
}
邏輯 AND 運算子 &&
當你只想在條件為真時渲染某些內容,條件為假時不渲染任何東西,可以使用 && 邏輯運算子:
function Notification({ hasMessages, messageCount }) {
return (
<div>
<h1>通知中心</h1>
{hasMessages && <p>你有 {messageCount} 則新訊息</p>}
</div>
)
}
語法:
{
條件 && 要渲染的內容
}
如果條件為 true,會渲染 && 後面的內容;如果條件為 false,則不渲染任何東西。
注意 && 的陷阱
使用 && 時要小心數字 0 的情況:
// ⚠️ 當 count 為 0 時,會渲染 "0" 而不是不渲染
{
count && <p>Count: {count}</p>
}
// ✅ 正確的寫法
{
count > 0 && <p>Count: {count}</p>
}
// ✅ 或者轉換成布林值
{
!!count && <p>Count: {count}</p>
}
邏輯 OR 運算子 ||
|| 運算子可以用來提供預設值:
function UserName({ name }) {
return <h1>Hello, {name || '訪客'}</h1>
}
// 如果 name 是空字串或 undefined,會顯示「Hello, 訪客」
Nullish Coalescing 運算子 ??
?? 運算子只在值為 null 或 undefined 時才使用預設值(不像 || 會對所有 falsy 值生效):
function Count({ count }) {
// 如果 count 是 0,會正確顯示 0
// 只有 count 是 null 或 undefined 時才顯示預設值
return <p>數量:{count ?? '未設定'}</p>
}
將元素存在變數中
當條件邏輯比較複雜時,可以先將元素存在變數中:
function LoginControl() {
const [isLoggedIn, setIsLoggedIn] = useState(false)
// 根據狀態決定要顯示的按鈕
let button
if (isLoggedIn) {
button = <button onClick={() => setIsLoggedIn(false)}>登出</button>
} else {
button = <button onClick={() => setIsLoggedIn(true)}>登入</button>
}
return (
<div>
<h1>{isLoggedIn ? '歡迎!' : '請登入'}</h1>
{button}
</div>
)
}
不渲染任何內容
有時候你希望元件在某些條件下不要渲染任何東西。這時可以 return null:
function WarningBanner({ show, message }) {
// 不顯示警告時,直接返回 null
if (!show) {
return null
}
return <div className="warning">⚠️ {message}</div>
}
// 使用
function App() {
const [showWarning, setShowWarning] = useState(true)
return (
<div>
<WarningBanner show={showWarning} message="這是警告訊息" />
<button onClick={() => setShowWarning(!showWarning)}>
{showWarning ? '隱藏' : '顯示'}警告
</button>
</div>
)
}
從元件返回
null 不會影響元件的生命週期。多重條件
當有多個條件需要判斷時,可以使用多個 if else 或串連的三元運算子:
使用 if else
function StatusIcon({ status }) {
if (status === 'success') {
return <span>✅</span>
} else if (status === 'error') {
return <span>❌</span>
} else if (status === 'loading') {
return <span>⏳</span>
}
return <span>❓</span>
}
使用物件映射
當條件很多時,使用物件映射會更清晰:
function StatusIcon({ status }) {
const icons = {
success: '✅',
error: '❌',
loading: '⏳',
default: '❓',
}
return <span>{icons[status] || icons.default}</span>
}
使用 switch
function StatusMessage({ status }) {
switch (status) {
case 'loading':
return <p>載入中...</p>
case 'success':
return <p>操作成功!</p>
case 'error':
return <p>發生錯誤</p>
default:
return null
}
}
實際範例:登入狀態管理
import { useState } from 'react'
function App() {
const [user, setUser] = useState(null)
function handleLogin() {
// 模擬登入
setUser({ name: 'Mike', email: 'mike@example.com' })
}
function handleLogout() {
setUser(null)
}
return (
<div>
<header>
{user ? (
<div>
<span>歡迎,{user.name}!</span>
<button onClick={handleLogout}>登出</button>
</div>
) : (
<button onClick={handleLogin}>登入</button>
)}
</header>
<main>{user ? <Dashboard user={user} /> : <WelcomePage />}</main>
</div>
)
}
function Dashboard({ user }) {
return (
<div>
<h1>個人儀表板</h1>
<p>Email: {user.email}</p>
</div>
)
}
function WelcomePage() {
return (
<div>
<h1>歡迎來到我們的網站</h1>
<p>請登入以查看更多內容</p>
</div>
)
}