
React 中如何優雅地處理條件渲染一句話總結三元表達式適合「二選一」 適合「顯示/隱藏」立即執行函數 IIFE 復雜邏輯兜底抽出子組件才是終極方案。別在 JSX 里寫 if-else用對了方式條件渲染既干凈又不容易出 bug正文目錄條件渲染有哪些方式5 大高頻場景 代碼示例萬能兜底條件渲染決策表預防 checklist不再踩坑一句話總結一、條件渲染有哪些方式問題背景JSX 本質是 JavaScript不能直接寫if-elseReact 提供了多種條件渲染方式但用錯了會導致渲染異常、性能浪費或代碼可讀性差。方式適用場景特點三元表達式? :二選一簡潔返回值邏輯與顯示/隱藏短路求值IIFE 立即執行函數復雜邏輯可寫 if-else但可讀性差抽取子組件復用/復雜條件最推薦可維護switch IIFE多條件分支比 if-else 清晰enum對象映射狀態映射渲染最優雅的多分支// ? 錯誤JSX 中不能直接寫 if-else function App({ status }) { return ( div if (status loading) { // 這會被當字符串渲染 Loading / } /div ) }二、5 大高頻場景 代碼示例場景 1加載狀態 → 用 最常見場景數據沒加載完顯示 Loading加載完顯示內容。// ? 正確 適合「滿足條件才顯示」 function UserList({ users, loading }) { return ( div {loading Spinner /} {!loading users.map(u div key{u.id}{u.name}/div)} /div ) }// ? 錯誤 與數字 0 的坑 function App({ count }) { return ( div {count Badge text{count} /} /div ) } // count 為 0 時渲染出 0 而不是什么都不顯示// ? 正確避免 0 的坑 function App({ count }) { return ( div {count 0 Badge text{count} /} {/* 或 */} {!!count Badge text{count} /} /div ) }場景 2二選一 → 用三元表達式登錄/未登錄、有數據/空狀態用三元最清晰。// ? 正確三元表達式二選一 function Greeting({ user }) { return ( div {user ? Welcome name{user.name} / : LoginButton /} /div ) }// ? 不推薦 疊 實現二選一 function Greeting({ user }) { return ( div {user Welcome name{user.name} /} {!user LoginButton /} /div ) } // 能用但啰嗦且兩個條件都執行場景 3多狀態切換 → 用對象映射loading / success / error 三種狀態用對象映射比 if-else 優雅得多。// ? 正確對象映射清晰優雅 function StatusView({ status, data, error }) { const statusMap { loading: Spinner /, success: DataList data{data} /, error: ErrorMessage error{error} /, empty: EmptyState / } return div{statusMap[status] ?? DefaultView /}/div }// ? 糟糕嵌套三元表達式難以閱讀 function StatusView({ status, data, error }) { return ( div {status loading ? Spinner / : status success ? DataList data{data} / : status error ? ErrorMessage error{error} / : EmptyState /} /div ) }場景 4復雜條件邏輯 → 抽子組件條件里有循環、有副作用、有復雜判斷抽成子組件最清晰。// ? 正確復雜邏輯抽子組件 function ProductList({ products, filter, sort }) { return ( div ProductGrid products{products} filter{filter} sort{sort} / /div ) } function ProductGrid({ products, filter, sort }) { const visible products .filter(filter) .sort(sort) if (visible.length 0) { return EmptyState message沒有符合條件的商品 / } return ( ul {visible.map(p ( li key{p.id}{p.name} - ¥{p.price}/li ))} /ul ) }// ? 糟糕在 JSX 里塞一堆邏輯 function ProductList({ products, filter, sort }) { return ( div {(() { const visible products.filter(filter).sort(sort) if (visible.length 0) { return EmptyState message沒有符合條件的商品 / } return ( ul {visible.map(p ( li key{p.id}{p.name} - ¥{p.price}/li ))} /ul ) })()} /div ) } // IIFE 能用但可讀性差lint 也不推薦場景 5條件 className → 用工具函數條件渲染不只是組件className 的條件拼接也是高頻場景。// ? 正確用 clsx / classnames 工具 import clsx from clsx function Button({ variant, size, disabled, children }) { return ( button className{clsx( btn, btn-${variant}, // btn-primary / btn-secondary btn-${size}, // btn-sm / btn-lg { btn-disabled: disabled, // 條件為 true 時添加 btn-active: !disabled } )} {children} /button ) }// ? 糟糕手動拼接字符串 function Button({ variant, size, disabled }) { let className btn btn- variant btn- size if (disabled) { className btn-disabled } else { className btn-active } return button className{className}Click/button }三、萬能兜底條件渲染決策表場景推薦方式示例滿足條件才顯示{loading Spinner /}二選一三元表達式{user ? A / : B /}三選一及以上對象映射statusMap[status]復雜邏輯判斷抽子組件ProductGrid ... /條件 classNameclsx工具clsx(btn, { active })數字 0 的坑 0 或!!{count 0 Badge /}組件 show/hide 頻繁切換CSSdisplaydiv style{{ display: show ? : none }}萬能決策流程條件有幾個分支 → 1 個滿足才顯示→ 用 → 2 個 → 用三元表達式 → 3 個及以上 → 用對象映射 → 邏輯太復雜 → 抽子組件// 萬能模板 function View({ status, data, error }) { // 復雜邏輯先抽出來 if (status loading) return Spinner / if (status error) return ErrorMessage error{error} / if (!data || data.length 0) return EmptyState / // 簡單條件用 return ( div {data.length 10 Pagination total{data.length} /} DataList data{data} / /div ) }四、預防 checklist不再踩坑左側是數字時用 0或!!避免0被渲染不要在 JSX 中寫if-else用三元或 IIFE嵌套三元超過 2 層 → 換對象映射或抽子組件IIFE 只在萬不得已時用優先抽子組件組件內提前return處理 loading/error 狀態減少嵌套條件 className 用clsx/classnames不要手動拼字符串頻繁切換的組件用 CSSdisplay而非卸載/掛載保留狀態switch語句放在組件外部或 IIFE 中不要直接寫在 JSX五、一句話總結一個分支用 兩個分支用三元三個以上用對象映射邏輯復雜就抽子組件——條件渲染的本質就是把 if-else 翻譯成 JSX 能接受的形式。最后問候親愛的朋友們并邀請你們閱讀我的全新著作 《React進階之路》