当前位置: 首页 > news >正文

条件渲染

组件经常需要根据不同条件显示不同内容。在React中,你可以使用类似于if语句、&&和?:运算符的JavaScript语法有条件地呈现JSX。

你将学到:

  • 如何根据条件返回不同的JSX

  • 如何有条件地包含或排除一段JSX

  • 在React代码库中常见的条件语法快捷方式

有条件地返回JSX

假设你有一个PackingList组件,渲染多个项目,这些项目可以标记为已打包或未打包:

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属性被设置为true,而不是false。如果isPacked={true},你想在已打包的项目中添加一个勾号(✔)。

你可以使用if/else语句编写如下:

if (isPacked) {return <li className="item">{name} ✔</li>;
}
return <li className="item">{name}</li>;

如果isPacked属性为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”。

现在假设你想要将完成的条目文本包装在另一个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中,标记是代码的一部分,因此您可以使用变量和函数等工具来整理复杂的表达式。

逻辑与(&&)运算符

你会遇到的另一个常用的快捷方式是JavaScript的逻辑与(&&)运算符。在React组件中,当您希望在条件为真时呈现一些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 一样,并在其位置上不呈现任何内容。

💡 陷阱:不要将数字放在 && 的左侧。

为了测试条件,JavaScript 会自动将左侧转换为布尔值。但是,如果左侧是 0,则整个表达式得到的值就是 0,而 React 将愉快地呈现 0 而不是什么都不呈现。

例如,常见的错误是编写类似 messageCount && <p>New messages</p> 的代码。很容易假设当 messageCount 为 0 时,它什么也不呈现,但它实际上会呈现 0 本身!

要修复它,请将左侧设置为布尔值:messageCount > 0 && <p>New messages</p>

有条件地将 JSX 赋给变量

当快捷方式妨碍编写普通代码时,请尝试使用 if 语句和变量。您可以使用 let 定义的变量进行重新赋值,因此首先提供您要显示的默认内容,即名称:

let itemContent = name;

使用 if 语句将 JSX 表达式重新分配给 itemContent(如果 isPacked 为 true):

if (isPacked) {itemContent = name + " ✔";
}

花括号打开了“JavaScript 的窗口”。使用花括号嵌套先前计算出的表达式,将变量嵌入返回的 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,则不必使用它们。

c3c03f116afb7b578b9ad39a47b71b33.png

长按关注

帮助 10W 人入门并进阶前端

http://www.lryc.cn/news/56189.html

相关文章:

  • springboot(10)异步任务
  • 清华大学开源的chatGLM-6B部署实战
  • 通过矩阵从整体角度搞懂快速傅里叶变换原理
  • 【C++从0到1】25、C++中嵌套使用循环
  • FastDFS与Nginx结合搭建文件服务器,并内网穿透实现公网访问
  • 密集场景下的行人跟踪替代算法,头部跟踪算法 | CVPR 2021
  • Matlab与ROS(1/2)---服务端和客户端数据通信(五)
  • 数字化转型的避坑指南:细说数字化转型十二大坑
  • pt05Encapsulationinherit
  • 面向对象编程(基础)9:封装性(encapsulation)
  • fate-serving-server增加取数逻辑并源码编译
  • 循环队列、双端队列 C和C++
  • 正则表达式(语法+例子)
  • Properties和IO流集合的方法
  • python 生成器、迭代器、动态新增属性及方法
  • Java处理JSON
  • 58-Map和Set练习-LeetCode692前k个高频单词
  • 线程生命周期及五种状态
  • OBCP第八章 OB运维、监控与异常处理-灾难恢复
  • 亚马逊云科技Serverless Data:数字经济下的创新动能
  • 【Ruby学习笔记】15.Ruby 异常
  • 聊聊MySQL主从延迟
  • 【C++从0到1】19、C++中多条件的if语句
  • 【多微电网】计及碳排放的基于交替方向乘子法(ADMM)的多微网电能交互分布式运行策略研究(Matlab代码实现)
  • Linux(centos7)安装防火墙firewalld及开放端口相关命令
  • Linux部署.Net Core Web项目
  • 【C++】STL之stack、queue的使用和模拟实现+优先级队列(附仿函数)+容器适配器详解
  • 第⑦讲:Ceph集群RGW对象存储核心概念及部署使用
  • 从异步到promise
  • Linux系统中进行JDK环境的部署