JSX,是一个 JavaScript 的语法扩展。是React组件编写UI逻辑的语言扩展(JSX除了能在React中使用之外还可以用于别的地方)。JSX 可以很好地描述 UI 应该呈现出它应有交互的本质形式。JSX 可能会使人联想到模版语言,但它具有 JavaScript 的全部功能。
JSX 有以下优点:
- JSX 执行更快,因为它在编译为 JavaScript 代码后进行了优化。
- 它是类型安全的,在编译过程中就能发现错误。
- 使用 JSX 编写模板更加简单快速。
JSX 原理
JSX 能在HTML中正常显示必须转换成 DOM,了解更多关于 DOM 的知识请移步DOM 概述,
DOM 将文档解析为一个由节点和对象(包含属性和方法的对象)组成的结构集合。DOM 是web页面的完全的面向对象表述,即每个DOM元素的结构都可以用JavaScript的对象来表示。
下面这个最简单的DOM元素为例,怎么使用JavaScript的对象来表现一个DOM元素的结果:1
<h1 class="title">Hello World!</h1>
你会发现,DOM元素包含的信息其实只有三个:标签名(HTML元素)、属性(HTML元素属性)和子元素(HTML元素或文本节点)。那么上面的这个HTML标签对应的所有信息可以用下面这个对象来描述:1
2
3
4
5
6
7{
tag: 'div',
attrs: {
className: 'title'
},
children: 'Hello World!'
}
HTML的信息和JavaScript所包含的结构和信息其实是一样的,我们可以用JavaScript对象来描述所有能用HTML表示的UI信息。
在React中会把类似HTML的JSX结构转换成JavaScript的对象结构,如:1
const element = <h1 className="title">Hello World!</h1>
JSX 实际是一个对象,element包含以下信息:1
2
3
4
5
6
7{
type: "h1",
props: {
children: "Hello World!",
className: "title"
}
}
Babel会把JSX转译成一个名为React.createElement()函数调用。比如下面的两段代码,起到的作用是同等的:1
2
3
4
5const element = (
<h1 className="greeting">
Hello, world!
</h1>
);
1 | const element = React.createElement( |
实际上,JSX 仅仅只是React.createElement(component, props, …children)函数的语法糖。
使用大括号嵌入 JavaScript 表达式
在 JSX 语法中,你可以在大括号内放置任何有效的 JavaScript 表达式:1
2const name = 'Josh Perez';
const element = <h1>Hello, {name}</h1>;
嵌入函数:1
2const getName = () => 'Josh Perez';
const element = <h1>Hello, {getName()}</h1>;
注意:if 语句以及 for 循环不是 JavaScript 表达式,所以不能在 JSX 中直接使用。但是,你可以用在 JSX 以外的代码中。
JSX 也是一个表达式
在编译之后,JSX 表达式会被转为普通 JavaScript 函数调用,并且对其取值后得到 JavaScript 对象。
也就是说,你可以在 if 语句和 for 循环的代码块中使用 JSX,将 JSX 赋值给变量,把 JSX 当作参数传入,以及从函数中返回 JSX:1
2
3
4
5
6
7
8
9
10const getName = () => 'jofun'
function getGreeting (name) {
if (name) {
return <h1>Hello, {name}</h1>
}
return <h1>Hello, {getName()}</h1>
}
const element = <div>{getGreeting('joe')}</div>
JSX 特定属性
你可以通过使用引号,来将属性值指定为字符串字面量:1
const element = <div tabIndex="0"></div>
使用大括号,来在属性值中插入一个 JavaScript 表达式:1
const element = <img src={user.avatarUrl} />
在属性中嵌入 JavaScript 表达式时,不要在大括号外面加上引号。你应该仅使用引号(对于字符串值)或大括号(对于表达式)中的一个,对于同一属性不能同时使用这两种符号。
注意:因为 JSX 语法上更接近 JavaScript 而不是 HTML,所以 React DOM 使用 camelCase(小驼峰命名)来定义属性的名称,而不使用 HTML 属性名称的命名约定。如:tabindex 变为 tabIndex。需要特别注意的是,在JSX中要是会用到class和for属性时,需要将class换成 className,for换成 htmlFor。那是因为class和for是JavaScript中的关键字。
使用 JSX 指定子元素
JSX 标签里和HTML一样能够嵌套包含子元素:1
2
3
4
5
6const element = (
<div>
<h1>Hello!</h1>
<h2>Good to see you here.</h2>
</div>
);
JSX 防止注入攻击
你可以安全地在 JSX 当中插入用户输入内容:1
2
3const title = response.potentiallyMaliciousInput;
// 直接使用是安全的:
const element = <h1>{title}</h1>;
React DOM 在渲染所有输入内容之前,默认会进行转义。它可以确保在你的应用中,永远不会注入那些并非自己明确编写的内容。所有的内容在渲染之前都被转换成了字符串。这样可以有效地防止 XSS(cross-site-scripting, 跨站脚本)攻击。