专栏首页JavaEdge深入了解React.js的JSX1 JSX 与HTML2 JSX 和HTML 的不同之处

深入了解React.js的JSX1 JSX 与HTML2 JSX 和HTML 的不同之处

JSX 是React 为JavaScript 语法带来的可选扩展,用于在JavaScript 代码中编写声明式XML 风格语法。

对于Web 项目而言,React 的JSX 提供了一组类似于HTML 的XML 标签,但在其他使用场景中,会使用其他组XML 标签来描述用户界面(如React with SVG、React Canvas和React Native)。转译后,XML 会被转换为针对React 库的函数调用。这行代码:

<h1>Hello World</h1> 

会被转译为:

React.createElement("h1", null, "Hello World"); 

JSX 是可选的。但拥抱它会带来如下好处

  • XML 包含特性的元素树非常适合表示UI。
  • 能够更精确和更方便地呈现应用程序的结构。
  • 是普通JavaScript,并不会改变这门语言的语义。

1 JSX 与HTML

对于Web 场景而言,JSX 看上去就像HTML,但它并不是HTML 规范的具体实现。React 的创造者只是让JSX 足够像HTML,这样就可以用来正确地描述Web 界面,并没有忽略这样一个事实,即它仍然应该遵循JavaScript 的风格和语法

2 JSX 和HTML 的不同之处

2.1 标签特性采取驼峰式大小写风格

例如,在HTML 中,输入标签可以包含一个可选的maxlengh 特性: <input type="text" maxlength="30"/> 在JSX 中,该特性应该写作maxLength(请注意大写字母“L”): return <input type="text" maxLength="30" />

2.2 所有元素都必须闭合

由于JSX 是XML,因此元素都必须闭合。诸如 和<img>这样的标签并不包含结束标签,需要自闭合。所以要使用<br/>而不是<br>,要使用<imgsrc="..."/>而不是<imgsrc="...">

2.3 特性名称基于DOM API

这一点可能难以理解,但实际上却非常简单。在与DOM API 进行交互时,标签特性的名称可能会和在HTML 中使用时有所不同。其中一个例子是class 和className。例如,对于这段普通的HTML: <div id="box" class="some-class"></div> 如果你想要使用普通JavaScript 来操作DOM 并更改它的类名,你可能会编写这样的代码: document.getElementById("box").className="some-other-class" 在JavaScript 中,这个特性称为className 而不是class。由于JSX 只是JavaScript的一种语法扩展,它遵循了DOM 所定义的特性命名规范。同样的div 用JSX 来表示就应该是: return <div id="box" className="some-class"></div>

2.3 JSX 的怪异之处

JSX 偶尔也比较奇怪。针对在使用JSX 构建组件时可能会遇到的常见问题,本节汇总了一些小技巧、提示和策略来供你应对。

  • 单一根节点 React 组件只能渲染一个根节点。想要了解这个限制的原因,我们先来看看render函数的一个返回示例:
return(  
    <h1>Hello World</h1> 
) 

它会被转换成一条语句:

return React.createElement("h1",null,"Hello World");

但是,下面的代码却不是合法的:

return (  
<h1>Hello World</h1> 
<h2>Have a nice day</h2> 
) 

需要明确的是,这并非JSX 的限制,而是JavaScript 的一个特性:一条返回语句只能返回单个值,而在前面的代码中我们尝试返回两条语句(两次React.createElement 调用)。解决的方法非常简单:就像你在普通JavaScript 中会做的那样,将所有返回值包含到一个根对象中。

return (  
<div> 
<h1>Hello World</h1> 
<h2>Have a nice day</h2> 
</div> 
) 

它完全有效,因为它会被转换成:

return React.createElement("div",null,  
React.createElement("h1",null,"Hello World"),  
React.createElement("h2",null," Have a nice day"),  
) 

它返回单个值,并且是通过合法的JavaScript 完成的。

  • 条件语句 如果语句不兼容于JSX,看上去像是JSX 的限制所致,实际上却是因为JSX 只是普通的JavaScript 回顾一下JSX 是如何被转换为普通JavaScript 如下JSX
return (  
      <div className="salutation">Hello JSX</div> 
) 

会被转换成这样的JavaScript

return (  
    React.createElement("div",{className:"salutation"},"Hello JSX");  
) 

然而,如果尝试在JSX 的中间编写if 语句,例如: <div className={if (condition) { "salutation" }}>Hello JSX</div>

它就会被转换成一个非法的JavaScript 表达式,如图2-1 所示:

image

  • 有什么解决方法? 尽管并无可能在JSX 中使用“if”语句,但仍有根据条件渲染内容的方法,包括使用三元表达式和将条件赋值给一个变量(空值和未定义的值都会被React 进行处理,JSX在转义时什么都不会输出)。

使用三元表达式

如果你有一个非常简单的表达式,可以使用三元形式:

render() {  
  return (  
    <div className={condition ? "salutation" : ""}> 
      Hello JSX  
    </div> 
  )  
} 

这段代码会被转换成一段合法的JavaScript:

React.createElement("div",{className: condition ?"salutation" : ""},  
"Hello JSX"); 

三元形式还可用来有条件地渲染整个节点:

<div> 
{condition ?  
<span>Hello JSX</span> 
: null}  
</div> 

将条件外置

如果三元表达式还不能应付你的要求,解决方法是不要在JSX 的中间使用条件。简单地将条件语句移动到外部(就像你在第2 章中隐藏和显示ContactItem 细节时所采取的方法)。

下面是原先的代码:

1.  render() {  
2.  return (  
3.  <div className={if (condition) { "salutation" }}> 
4.  Hello JSX  
5.  </div> 
6.  )  
7.  } 

将条件移动到JSX 的外部,就像:

render() {  
let className;  
if(condition){  
className = "salutation";  
}  
return (  
<div className={className}>Hello JSX</div> 
)  
} 

React 知道如何处理未定义的值,如果条件为假,它甚至不会在div 标签中创建class特性。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • React.js 实战之 JSX 简介在 JSX 中使用表达式JSX 本身其实也是一种表达式JSX 属性JSX 嵌套JSX 防注入攻击JSX 代表 ObjectsJSX 的怪异之处

    这种看起来可能有些奇怪的标签语法既不是字符串也不是 HTML 它被称为 JSX, 一种 JavaScript 的语法扩展 推荐在 React 中使用 JSX...

    JavaEdge
  • DDD领域驱动设计实战(三)- 理解实体

    传统开发人员总将关注点放在数据,而不是领域。因为在软件开发中,DB占据主导地位。首先考虑的是数据的属性(即数据库的列)和关联关系(外键关联),而不是富有行为的领...

    JavaEdge
  • 操作系统之文件管理

    按文件性质和用途分类(UNIX),一般分为普通文件、目录文件、特殊文件(设备文件)、管道文件、套接字

    JavaEdge
  • 八.CSS之animation(动画)

    ​ 多个属性间使用,隔开 ​ 如果所有属性都需要过渡,则使用all关键字 ​ ...

    小海怪的互联网
  • CSS Margin塌陷(重叠)

    在标准文档流中,竖直方向(是竖直方向,水平方向的不会出现塌陷现象)的margin会出现叠加现象,即较大的margin会覆盖掉较小的margin,竖直方向的两个盒...

    Coxhuang
  • day49_BOS项目_01

    其余步骤参考如下链接: https://www.cnblogs.com/chenmingjun/p/9513143.html#_label0 右键项目 -->...

    黑泽君
  • React.js 实战之 JSX 简介在 JSX 中使用表达式JSX 本身其实也是一种表达式JSX 属性JSX 嵌套JSX 防注入攻击JSX 代表 ObjectsJSX 的怪异之处

    这种看起来可能有些奇怪的标签语法既不是字符串也不是 HTML 它被称为 JSX, 一种 JavaScript 的语法扩展 推荐在 React 中使用 JSX...

    JavaEdge
  • css的position定位详解

    iii.  父级元素定位(绝对定位absolute)的子元素absolute定位情况:都不保留原文档流空白

    十月梦想
  • 详解:28 box-shadow开端

    /这是比如pink的宽150高150的东西,然后是x往右20 往下50的移动/ 兄弟们,记住一句核心:右下为正,左下为负。 记住哈,兄弟们,移动只有两个哈,...

    用户7873631
  • js拖拽

    用户7873631

扫码关注云+社区

领取腾讯云代金券