在 React 开发中,我们经常需要根据不同条件显示不同内容 —— 比如用户登录后显示个人中心,未登录时显示登录按钮;数据加载中显示 loading 状态,加载完成后显示内容。这种 “根据条件决定渲染什么” 的操作,就是条件渲染。
本文将带你系统学习 React 中 7 种常用的条件渲染方式,从基础到进阶,每种方式都配有代码示例和适用场景分析。
什么是条件渲染?
简单说,条件渲染就是根据特定条件(如变量值、状态、属性等),让组件呈现不同的 UI。
比如一个简单场景:
- 当用户已登录(
isLoggedIn = true
),显示 “欢迎回来,xxx” - 当用户未登录(
isLoggedIn = false
),显示 “请登录”
这就是最基础的条件渲染需求。React 没有专门的 “条件渲染语法”,而是通过 JavaScript 的逻辑结合 JSX 实现,非常灵活。
7 种常用的条件渲染方式
1. if/else 语句:最直观的条件判断
最基础也最容易理解的方式:用 JavaScript 的if/else
语句在组件中拆分不同渲染逻辑。
import { useState } from 'react';
function UserGreeting() {
const [isLoggedIn, setIsLoggedIn] = useState(false);
// 用if/else判断条件,返回不同JSX
if (isLoggedIn) {
return <h1>欢迎回来,用户!</h1>;
} else {
return <h1>请先登录~</h1>;
}
// 也可以在return前定义内容
// let content;
// if (isLoggedIn) {
// content = <h1>欢迎回来,用户!</h1>;
// } else {
// content = <h1>请先登录~</h1>;
// }
// return content;
}
适用场景:
- 逻辑较复杂的条件判断(比如多个条件组合)
- 需要在渲染前处理大量逻辑(如数据转换)
优点:直观易懂,符合 JavaScript 思维;适合复杂条件。
缺点:在 JSX 中无法直接使用,必须在 return 外处理。
2. 三元运算符:JSX 中直接写简单条件
三元运算符(condition ? exprIfTrue : exprIfFalse
)可以直接嵌入 JSX 中,适合简单的二选一渲染。
import { useState } from 'react';
function ScoreDisplay() {
const [score, setScore] = useState(75);
return (
<div>
<p>你的成绩:{score}</p>
{/* 三元运算符直接写在JSX中 */}
<p>{score >= 60 ? '恭喜,及格了!' : '抱歉,未及格'}</p>
</div>
);
}
适用场景:
- 简单的二选一判断(是 / 否、大于 / 小于等)
- 需要在 JSX 中直接嵌入条件逻辑
优点:简洁,可直接嵌入 JSX;适合简单条件。
缺点:条件复杂时可读性差(不建议嵌套三元运算符)。
3. 逻辑与 (&&) 运算符:满足条件才渲染元素
当你需要 “条件满足时显示某个元素,不满足时不显示”(而不是显示另一个元素),可以用&&
运算符。
import { useState } from 'react';
function Notification() {
const [unreadCount, setUnreadCount] = useState(3);
return (
<div>
<h2>消息中心</h2>
{/* 当unreadCount > 0时,显示小红点和数量 */}
{unreadCount > 0 && (
<span style={{
backgroundColor: 'red',
color: 'white',
borderRadius: '50%',
padding: '2px 6px',
marginLeft: '8px'
}}>
{unreadCount}
</span>
)}
</div>
);
}
原理:
JavaScript 中,true && expr
会返回expr
,false && expr
会返回false
,而 React 会忽略false
的渲染。
注意:
- 避免用 0 作为条件值,因为
0 && ...
会渲染 0(而非不渲染)。
解决:unreadCount > 0 && ...
(明确返回布尔值)。
适用场景:
- 条件满足时渲染某个元素,不满足时不渲染(单分支)
- 简单的 “存在即显示” 逻辑(如未读消息、提示标签)
4. 元素变量:先存后用,适合多条件
先将不同条件对应的 JSX 赋值给变量,再在 return 中使用变量。适合多条件分支场景。
import { useState } from 'react';
function UserRole() {
const [role, setRole] = useState('user'); // 可能的值:'user' | 'admin' | 'guest'
// 定义元素变量,根据条件赋值
let roleDesc;
if (role === 'admin') {
roleDesc = <p>您拥有管理员权限,可以管理所有内容</p>;
} else if (role === 'user') {
roleDesc = <p>您是普通用户,可以查看和编辑自己的内容</p>;
} else {
roleDesc = <p>您是访客,仅可查看公开内容</p>;
}
return (
<div>
<h2>用户权限</h2>
{roleDesc} {/* 使用变量 */}
</div>
);
}
适用场景:
- 多个条件分支(3 个及以上)
- 需要在渲染前对元素进行额外处理(如添加样式、绑定事件)
优点:逻辑清晰,变量名可增强可读性;避免 JSX 中混入大量条件判断。
5. switch-case 语句:多分支条件的规范写法
当条件分支较多(如根据不同状态码显示不同提示),用switch-case
比if/else
更整洁。
import { useState } from 'react';
function StatusMessage() {
const [status, setStatus] = useState('pending'); // 'pending' | 'success' | 'error' | 'warning'
// 用switch-case返回不同内容
function getMessage() {
switch (status) {
case 'pending':
return <p>加载中,请稍候...</p>;
case 'success':
return <p style={{ color: 'green' }}>操作成功!</p>;
case 'error':
return <p style={{ color: 'red' }}>操作失败,请重试</p>;
case 'warning':
return <p style={{ color: 'orange' }}>注意:数据不完整</p>;
default:
return <p>未知状态</p>;
}
}
return (
<div>
<h2>操作状态</h2>
{getMessage()} {/* 调用函数返回结果 */}
</div>
);
}
适用场景:
- 多个固定值的条件分支(如状态码、类型标识)
- 需要明确 “默认情况”(
default
分支)的场景
优点:结构清晰,比多个if/else if
更易维护;强制考虑默认情况。
6. 自定义条件组件:封装复用条件逻辑
如果多个组件需要相同的条件渲染逻辑,可以封装成自定义组件,提高复用性。
// 封装一个"权限控制组件"
function WithPermission({ permission, children, fallback = null }) {
// 模拟权限判断逻辑(实际项目可能更复杂)
const hasPermission = checkUserPermission(permission);
// 有权限则显示children,否则显示fallback
return hasPermission ? children : fallback;
}
// 模拟权限检查函数
function checkUserPermission(permission) {
const userPermissions = ['read', 'edit']; // 假设用户拥有的权限
return userPermissions.includes(permission);
}
// 使用示例
function Dashboard() {
return (
<div>
<h1>控制台</h1>
{/* 所有用户可见 */}
<p>欢迎来到控制台</p>
{/* 仅有权限'edit'的用户可见 */}
<WithPermission permission="edit" fallback={<p>无编辑权限</p>}>
<button>编辑内容</button>
</WithPermission>
{/* 仅有权限'delete'的用户可见(无权限时不显示) */}
<WithPermission permission="delete">
<button>删除内容</button>
</WithPermission>
</div>
);
}
适用场景:
- 多个组件需要相同的条件逻辑(如权限控制、角色判断)
- 条件逻辑较复杂,需要集中维护
优点:逻辑复用,减少重复代码;组件职责单一,更易测试。
7. 动态导入 + Suspense:按需加载组件(React 18+)
对于大型应用,可根据条件动态导入组件(未满足条件时不加载组件代码),配合Suspense
显示加载状态。
import { Suspense, useState, lazy } from 'react';
// 动态导入组件(只在需要时加载)
const PremiumFeature = lazy(() => import('./PremiumFeature'));
const FreeFeature = lazy(() => import('./FreeFeature'));
function App() {
const [isPremium, setIsPremium] = useState(false);
return (
<div>
<h1>应用功能</h1>
{/* 免费功能始终显示 */}
<Suspense fallback={<p>加载免费功能中...</p>}>
<FreeFeature />
</Suspense>
{/* 付费功能仅付费用户可见,且仅在需要时加载代码 */}
{isPremium && (
<Suspense fallback={<p>加载高级功能中...</p>}>
<PremiumFeature />
</Suspense>
)}
</div>
);
}
适用场景:
- 大型应用的代码分割(减少初始加载体积)
- 条件触发的 “重量级” 组件(如付费功能、模态框)
优点:优化性能,减少不必要的代码加载;配合 Suspense 提升用户体验。
三、条件渲染避坑的点
- 避免渲染
undefined
确保条件判断的分支都有返回值,否则可能出现undefined
导致的白屏。
不好的示例:{condition && undefined}
(会渲染undefined
) - 谨慎嵌套条件
多层嵌套的三元运算符或if/else
会导致代码可读性差,建议拆分为多个组件或用元素变量。 - 注意 falsy 值的渲染
React 会渲染0
、''
(空字符串)等 falsy 值,而非忽略它们。
解决:用!!
转为布尔值,或明确判断> 0
等。
四、如何选择合适的方式?
方式 | 适用场景 | 优点 | 缺点 |
---|---|---|---|
if/else | 复杂逻辑、多条件组合 | 直观,适合复杂逻辑 | 不能直接嵌入 JSX |
三元运算符 | 简单二选一条件 | 简洁,可嵌入 JSX | 复杂条件可读性差 |
逻辑与 (&&) | 单分支(满足条件才显示) | 极简,适合简单判断 | 需注意 falsy 值渲染问题 |
元素变量 | 多条件分支,需预处理元素 | 逻辑清晰,易维护 | 需额外定义变量 |
switch-case | 多个固定值的分支(如状态码) | 结构规范,强制默认分支 | 代码量略多 |
自定义条件组件 | 复用条件逻辑(如权限控制) | 复用性好,职责单一 | 需要额外封装 |
动态导入 + Suspense | 大型应用按需加载组件 | 优化性能,减少初始体积 | 需 React 18 + 支持 |
记住:没有 “最好” 的方式,只有 “最合适” 的方式。根据条件复杂度、复用需求和项目场景选择即可。
以上就是本文的全部内容了,想了解更多React用法可以在《React中文教程》里查阅
共同學習,寫下你的評論
評論加載中...
作者其他優質文章