React 条件渲染与 JSX 进阶
前置:React 列表与表单
目标:熟练用
&&、三元、提前 return;空列表要有兜底。
引言
React 里「要不要显示某块 UI」几乎全靠 条件渲染 。写法不多,但坑不少------尤其是 && 遇上 0。
本篇 demo:登录切换、角色面板、空菜单兜底。
动手
完整代码:react2/09-conditional-jsx/demo
bash
cd react2/09-conditional-jsx/demo
npm install && npm run dev
点「登录 / 退出」「角色」看界面怎么变。
1. 三元:二选一
登录态用三元最直观:
tsx
{loggedIn ? <p className="ok">已登录</p> : <p>请先登录</p>}
按钮文案同理:
tsx
<button type="button" onClick={() => setLoggedIn((v) => !v)}>
{loggedIn ? '退出' : '登录'}
</button>
两边都要占位时用三元;只想「有条件才出现」用下面的 &&。
2. &&:有条件才显示
管理员面板:必须已登录 且 角色是 admin:
tsx
{role === 'admin' && loggedIn && <p>管理员面板可见</p>}
左侧为假时,React 不渲染右侧 JSX。
坑:{count && <X />}
tsx
// ❌ count 为 0 时,页面上会冒出一个「0」
{count && <Badge />}
// ✅ 先转成明确的布尔
{count > 0 && <Badge />}
{!!count && <Badge />}
原因:0 && <Badge /> 的结果是 0,而 0 是合法可渲染内容。
3. 空列表要有兜底
未登录时 items 是 [],直接 map 会得到空白------用户以为坏了。先判断长度:
tsx
const items = loggedIn ? ['仪表盘', '设置'] : []
{items.length === 0 ? (
<p>暂无菜单(未登录)</p>
) : (
<ul>
{items.map((x) => (
<li key={x}>{x}</li>
))}
</ul>
)}
列表篇学过 map + key;这篇补上 Empty 状态。
4. 提前 return
组件开头就把「没数据 / 没权限」挡掉,后面主 UI 更干净:
tsx
function Menu({ items }: { items: string[] }) {
if (items.length === 0) {
return <p>暂无菜单</p>
}
return (
<ul>
{items.map((x) => (
<li key={x}>{x}</li>
))}
</ul>
)
}
适合「整页 / 整块组件」级的分支;局部小开关继续用三元或 &&。
对照表
| 场景 | 写法 | 例子 |
|---|---|---|
| 二选一 | a ? <A /> : <B /> |
已登录 / 请先登录 |
| 有条件才显示 | ok && <Tip /> |
管理员面板 |
| 数字当条件 | n > 0 && <X /> |
避免渲染出 0 |
| 空列表 | len === 0 ? <Empty /> : map |
暂无菜单 |
| 整块提前结束 | if (!data) return <Empty /> |
独立子组件 |
demo 在练什么
App.tsx 里两块面板:
- 登录 + 角色 :三元文案 +
&&叠条件 - 菜单 :空数组走兜底文案,登录后
map出两项
自己改一改:给 guest 也加一项「帮助」,或加第三个角色看分支怎么扩。