前言
在React中,存在如下代码形式:
const element = <h1>Hello, world!</h1>;
这个有趣的标签语法既不是字符串也不是 HTML。
它被称为 JSX,是一个 JavaScript 的语法扩展。我们建议在 React 中配合使用 JSX,JSX 可以很好地描述 UI 应该呈现出它应有交互的本质形式。JSX 可能会使人联想到模板语言,但它具有JavaScript 的全部功能。
React 使用名为 JSX 的 JavaScript 语法扩展,可以直接在 JavaScript 中编写 HTML。 要做到这一点,只需在花括号中包含希望被视为 JavaScript 的代码:
{ 'this is treated as JavaScript code' }(这被视为 JavaScript 代码)
但是,由于浏览器不能解析 JSX,因此必须将 JSX 代码编译为 JavaScript。 在这个过程中,转换器 Babel 是一个很受欢迎的工具。
一、JSX与HTML区别
命名
因为 JSX 语法上更接近 JavaScript 而不是 HTML,所以 React DOM 使用 camelCase(小驼峰命名)来定义属性的名称,而不使用 HTML 属性名称的命名约定。例如,JSX 中的单击事件是 onClick,而不是 onclick。 同样,onchange 变成了onChange。
自动闭合规则
在HTML中,几乎所有的标签都有一个开始和结束标签:<div></div>
,结束标签在你要关闭的标签名之前始终具有正斜杠。 但是,HTML 中有一些称为 “自闭合标签” 的特殊实例,它们在另一个标签开始之前,不需要开始和结束标签都存在。
例如,换行标签可以写成 <br>
或者<br />
,但是不应该写成 <br></br>
,因为它不包含任何内容。
在 JSX 中,规则略有不同。 任何 JSX 元素都可以使用自闭合标签编写,并且每个元素都必须关闭。 例如,为了通过编译换行标签必须始终编写为 <br />
。 另一方面 <div>
可以写成 <div />
或者 <div></div>
。 不同之处在于,在第一个语法版本中,无法在 <div />
中包含任何内容。
二、JSX的基本用法
JSX 也是一个表达式
在编译之后,JSX 表达式会被转为普通 JavaScript 函数调用,并且对其取值后得到 JavaScript 对象。也就是说,你可以在 if 语句和 for 循环的代码块中使用 JSX,将 JSX 赋值给变量,把 JSX 当作参数传入,以及从函数中返回 JSX:
function getGreeting(user) {
if (user) {
return <h1>Hello, {formatName(user)}!</h1>;
}
return <h1>Hello, Stranger.</h1>;
}
JSX 中指定属性
你可以通过使用引号,来将属性值指定为字符串字面量:
const element = <div tabIndex="0"></div>;
也可以使用大括号,来在属性值中插入一个 JavaScript 表达式:
const element = <img src={user.avatarUrl}></img>;
在属性中嵌入 JavaScript 表达式时,不要在大括号外面加上引号。你应该仅使用引号(对于字符串值)或大括号(对于表达式)中的一个,对于同一属性不能同时使用这两种符号。
使用 JSX 指定子元素
假如一个标签里面没有内容,你可以使用 /> 来闭合标签:
const element = <img src={user.avatarUrl} />;
JSX 标签里能够包含很多子元素:
const element = (
<div>
<h1>Hello!</h1>
<h2>Good to see you here.</h2>
</div>
);
嵌套的 JSX
必须返回单个元素。
这个父元素将包裹所有其他级别的嵌套元素。例如,几个作为兄弟元素编写的 JSX 元素而没有父元素包裹将不会被转换。要将注释放在 JSX 中,可以使用 {/* */}
语法来包裹注释文本。这里是一个示例:
<div> //有效的JSX格式
<p>Paragraph One</p>
<p>Paragraph Two</p>
<p>Paragraph Three</p>
</div>
传递JSX
在 React 中,可以使用它的的渲染 API(ReactDOM)将此 JSX 直接渲染到 HTML DOM。
ReactDOM 提供了一个简单的方法来将 React 元素呈现给 DOM,如下所示:
ReactDOM.render(componentToRender, targetNode)
其中第一个参数是要渲染的 React 元素或组件,第二个参数是组件将要渲染到的 DOM 节点。
必须在 JSX 元素声明之后调用 ReactDOM.render(),就像在使用变量之前必须声明它一样。
JSX 表示对象
Babel 会把 JSX 转译成一个名为 React.createElement() 函数调用。
以下两种示例代码完全等效:
const element = (
<h1 className="greeting">
Hello, world!
</h1>
);
const element = React.createElement(
'h1',
{className: 'greeting'},
'Hello, world!'
);
React.createElement() 会预先执行一些检查,以帮助你编写无错代码,但实际上它创建了一个这样的对象:
// 注意:这是简化过的结构
const element = {
type: 'h1',
props: {
className: 'greeting',
children: 'Hello, world!'
}
};
这些对象被称为 “React 元素”。它们描述了你希望在屏幕上看到的内容。React 通过读取这些对象,然后使用它们来构建 DOM 以及保持随时更新。
总结
JSX的一些需要特别注意的地方:
-
如果在 JSX 中给元素添加类, 需要使用
className
代替class
; -
在 JSX 中可以直接使用 JS代码,直接在 JSX 中通过
{}
中间写 JS代码即可; -
在JSX 中只能使用表达式,但是不能出现语句。
-
在 JSX 中注释语法:
{/* 中间是注释的内容 */}