为什么 JSX 中只能使用表达式,而不能使用语句?

2024-02-09

在继续之前,我应该提到的是,是的,我已经阅读了“在 React JSX 中使用 if 语句 https://stackoverflow.com/questions/46156968/use-if-statement-in-react-jsx" 及其在 SO 和其他地方的不同变体。

然而,这些帖子更多的是关于how无需在 JSX 中使用语句即可解决问题。我想知道whyJSX 中不允许使用语句,我找不到任何关于 JSX 的帖子。

我正在阅读关于此的官方文档“JSX 中的 If-Else https://react-cn.github.io/react/tips/if-else-in-JSX.html“,给出的原因是,引用,

JSX 只是函数调用和对象构造的语法糖

他们继续对比以下两段代码,第一段有效,第二段无效:

这是有效的:

// This JSX: 
ReactDOM.render(<div id="msg">Hello World!</div>, mountNode);
// Is transformed to this JS: 
ReactDOM.render(React.createElement("div", {id:"msg"}, "Hello World!"), mountNode); 

这是无效的:

// This JSX:
<div id={if (condition) { 'msg' }}>Hello World!</div>

// Is transformed to this JS:
React.createElement("div", {id: if (condition) { 'msg' }}, "Hello World!");

我真的很想了解这一点。首先,在第二个例子中,我绝不会想到在idHTML 元素的属性。事实上,这是我第一次看到 id 属性中使用任何类型的代码。如果我尝试编写 if 条件,我只需在渲染返回表达式中用大括号括起来即可,作为其他可用 JS(如映射或三元表达式)的简单模拟。

render() {
return (
  {if ...
}
)

我毫不怀疑,本文档的作者非常清楚,这个有点非正统的示例解释了他们的断言“JSX 只是函数调用和对象构造的语法糖”,但我不知道如何解释。


让我们从概念上开始。语句与表达式的定义是什么?

一个声明可以做一些事情。表达式计算出一个值。

JSX 旨在构建并从一段代码传递到另一段代码,最终以 HTML 形式结束。这个名字甚至暗示了这种“JavaScript 到 XML”的转换。

它的重点是返回 HTML 节点的“值”。 JSX 允许使用表达式,因为它们可以帮助您确定值。

也许仔细研究三元表达式和 if/else 之间的区别会有所帮助。

If/Else

if(isSaturday){
   wakeUpHour = 10;
}else{
   wakeUpHour = 7;
}

Ternary

wakeUpHour = isSaturday ? 10 : 7;

两者都完成同样的事情,对吧?但在幕后,他们的运作方式有所不同。在英语中,if/else 可能是这样的:

  1. 如果 'isSaturday' 的值为 true,则运行大括号内的代码
  2. 将数字 10 分配给“wakeUpHour”
  3. 否则,运行下一个大括号内的代码
  4. 将数字 7 分配给“wakeUpHour”

三元语句也有两部分:

  1. 如果 isSaturday 为真,则值为 10。否则值为 7。
  2. 将此值分配给“wakeUpHour”

我们认为这些都完成了同样的事情。这里的关键点是三元表达式本身只是一个值。这不是几行代码。到做一点事该值需要另一部分,对其进行赋值。

在 JSX 中,我们不想分配东西。我们想要价值观。因此,我们只采用三元表达式(一个值),而不是赋值部分或任何其他代码语句。

最后,希望不要增加您的困惑,我要指出的是,您can在 JSX 中定义函数。

const myJSX = <button onClick={ () => { return 'hello'; } }>Say hello</button>

等等,什么?我以为我们无法执行代码行。它不是执行代码行,而是定义它们;它被渲染为:

var myJSX = React.createElement("button", {onClick: () => {
  return 'hello';
}}, "Say hello");

将其与尝试仅放入 if/else 语句进行比较:

const myJSX = <span>{ if(true){ return 'hello'; } }</span>

它会尝试渲染为:

var myJSX = React.createElement("span", null, if(true){ return 'hello' });

这是行不通的,出于同样的原因,您通常无法将未封装的代码块传递到函数的参数中。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 JSX 中只能使用表达式,而不能使用语句? 的相关文章

随机推荐

  • 从 MailItem (Microsoft.Office.Interop.Outlook) 获取唯一 ID?

    我正在创建一个应用程序来读取 Outlook 中收到的电子邮件 读取的过程大概是这样的 using Outlook Microsoft Office Interop Outlook var app new Outlook Applicati
  • 类似于 Bitbucket 的软件,我可以自行托管

    是否有类似于 Bitbucket 的系统可供我自行托管 我试图在网上四处看看是否有什么东西 但我似乎找不到任何东西 我们现在正在使用Redmine 但Redmine不支持每个项目多个存储库 我希望能够实现的 Bitbucket 功能包括分叉
  • 公共/受保护的类属性不会覆盖父类的私有属性吗?

    在父类上声明私有属性 然后在子类上将该属性重新声明为公共属性或受保护属性 当您创建 Child 类的实例并调用从 Parent 类继承的方法时 使用 Parent 类上的属性 而不是 Child 类上的属性 如果父类上的属性的初始声明是公共
  • 如何在 TinyMCE for Plone 中将 替换为

    我想在 TinyMCE 中用强标签替换粗体标签 如何在 Plone 中使用 Products TinyMCE 做到这一点 我读了TinyMCE文档 http www tinymce com wiki php Configuration va
  • 计算表结果:使用单选按钮值的 PHP switch case

    我编辑了这篇文章以便更好地理解 这是我作为学生实习生的第一个项目 它是一个记录计算机设备的设备监控系统 这是页面中的代码的一部分 该页面包含过滤选项和显示计算机设备列表的表格 过滤选项包含几个单选按钮 它们属于两个类别 状态 和 条件 请参
  • jQuery 连续鼠标按下

    我有以下代码片段 document mousedown function event doSomething 我可以捕获mousedown活动成功 我正在尝试执行以下操作 捕捉第一个mousedown event 我想检测用户是否仍然按住鼠
  • 如何在 C 中使用 printf 打印 unsigned long int ? [复制]

    这个问题在这里已经有答案了 可能的重复 如何在C中打印 unsigned long https stackoverflow com questions 3209909 how to printf unsigned long in gcc 我
  • 为什么我的愿望清单仅限于一项?

    我使用magento 1 9 我的愿望清单有问题 出于某种原因 它只会让我在我的愿望清单中包含一个项目 当我将另一个项目添加到愿望清单时 它会替换我的愿望清单中已有的项目 有配置中没有任何内容来限制愿望清单项目 我只是有点困惑为什么要这样做
  • 如何将 POST 请求重定向到在 MVC 中维护模型值的 url

    我有一个相当标准的排序 过滤器 页面搜索表单 但需要控制 url 的格式 排序 过滤器 页面参数都应该是 url 的一部分 以便可以将地址通过电子邮件发送给某人 当添加另一个过滤器参数时 会发出 POST 请求 我的控制器方法如下所示 Ht
  • RecyclerView 与 ImageView 以及不同的 Activity

    我拥有的 一个 RecyclerView 其中包含酒吧 咖啡店等地方的图片 我想要的 当您单击这些图像之一时 我会向您显示所选地点的信息 我的问题 我该如何设置OnCLickListener例如第三张图片 很多人告诉我在我的 onBindV
  • 如何在matplotlib条形图后面绘制网格线

    x 01 02 02 02 03 02 04 02 05 02 y 2 2 3 7 2 fig ax plt subplots 1 1 ax bar range len y y width 0 3 align center color sk
  • .htaccess 将所有内容重写到父目录

    我正在尝试重写对父目录的每个请求 这是我的 htaccess 的内容 RewriteEngine on RewriteRule 1 不幸的是 这不起作用并导致 错误请求 错误 这可能吗 应该夹在 之间 这样系统就知道它应该将表达式 记忆 为
  • Visual Studio 2017 控制台应用程序:预编译头

    最近我更新了我的 Visual Studio 2017 从那时起 我无法创建 Windows 控制台应用程序项目 文件 新建 项目 我选择了 已安装 Visual C Windows控制台应用程序 当我单击 确定 时 没有出现应用程序设置向
  • 将自定义变量/参数从电子邮件模板传递到 phtml 文件

    我被困在我的自定义代码中 我想将自定义变量从电子邮件模板传递到 pthml 文件 编辑文件 应用程序 代码 本地 法师 销售 模型 Order php 在这个函数中 public function sendNewOrderEmail def
  • linux inotify 事件用于重命名()并覆盖

    我有一个小型应用程序 它监视目录树中特定类型的文件名 monitored 它统计匹配文件的数量 使用 inotify 监视添加或删除匹配文件的各种事件 并可以轮询报告当前文件数量 以及过去几年添加和删除文件的平均速率秒 目录树可以包含数十万
  • 为开源贡献内部工具值得付出努力吗? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我知道这是一个普遍问题 但我想听听其他人对我们案例的看法 我在一家小公司工作 我们的主要开发工具是 PowerBuilder 这是一个非常有限的
  • OpenCV 的 .Net (dotNet) 包装器? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我见过有几个 opencvdotnet http code google com p opencvdo
  • 在 C++ 中是否有通过引用返回新对象实例的正确方法?

    所以我正在编写一些代码 我有这样的代码 class Box private float x y w h public Rectangle GetRect void const return Rectangle x y w h 然后在一些代码
  • boost find in共享内存方法陷入c++多进程项目中

    我正在使用 boost 的 ipc 库来保存复杂的对象 包括图像 在共享内存中 由多个进程使用 我们称这个对象为MyImage 共享内存是一个循环缓冲区 保存了几个MyImage一次对象 在我的代码中 有两个 或更多 进程写入共享内存中的一
  • 为什么 JSX 中只能使用表达式,而不能使用语句?

    在继续之前 我应该提到的是 是的 我已经阅读了 在 React JSX 中使用 if 语句 https stackoverflow com questions 46156968 use if statement in react jsx 及
Powered by Hwhale