React 的核心机制之一就是可以在内存中创建虚拟的 DOM 元素。React 利用虚拟 DOM 来减少对实际 DOM 的操作从而提升性能。
JSX(JavaScript XML)是一种在 React 组件内部构建标签的类 XML 语法。React 发明了 JSX,利用 HTML 语法来创建虚拟 DOM。当遇到<,JSX 就当 HTML 解析,遇到 { 就当 JavaScript 解析。
实际上 HTML 也是 XML 协议,由浏览器解析,而 JSX 是由 JS 解析,当然也可以通过构建工具解析完成,如 grunt、webpack,可以避免 JS 在运行中解析 JSX 所消耗的时间。JSX 原本是使用官方自己提供的方法处理, 2015-7-12日官方博客文章声明其自身用于 JSX 语法解析的编译器 JSTransform 已经过期,不再维护,React JS 和 React Native 已经全部采用第三方 Babel 的 JSX 编译器实现
JSX 并不是一门新的语言,仅仅是个语法糖(syntactic sugar),允许开发者在 JavaScript 中书写 HTML 语法。最后,每个 HTML 标签都转化为 JavaScript 代码来运行。
这样对于使用 JavaScript 来构建组件以及组件之间关系的应用,在代码层面显得更加清晰。而不再像过于一样用 JavsScript 操作 DOM 来创建组件以及组件之间的嵌套关系。
一、运行环境
- JSX 必须借助 ReactJS 环境才能运行,所以使用前要先加载 ReactJS 文件(react.js、react-dom.js)
- 除了 ReactJS 环境,还需要加载 JSX 的解析器(babel.js)
二、基本语法
1). JSX 必须严格闭合1
2
3
4
5// 报错
<div>
// 正确
<div/>
<div></div>
可以把 JSX 标签当做一个变量,可以在任何位置使用。1
2var tag = <div>I'm JSX tag</div>
ReactDom.render(div);
2). JSX 一个标签就是一个组件,当存在两个组件在同一级时,必须使用一个标签(组件)包起来。
下面是错误的写法:1
2<div></div>
<div></div>
正确的写法是1
2
3
4<tag>
<div></div>
<div></div>
<tag>
3). 自定义组件使用时必须首字母大写,首字母不大写直接解析为同名html标签。1
2
3<Test/> // 自定义
<div></div> // 直接解析为<div></div>
<test/> // 直接解析为<test></test>, 在浏览器时不识别的,无法显示。
三、代码转换
使用 JSX 的书写是为了让我们能更直观地看到组件的 DOM 结果,其最终还是通过解析器转化为 JavaScript 代码才能在浏览器端执行。
比如我们写了如下一段代码:1
var msg = <h1 width="10px">hello hangge.com</h1>;
那么解析器就会转化为:1
var msg = React.createElement("h1", {width: "10px"}, "hello hangge.com");
也就是说我们每写一个标签,就相当于调用一次 React.createElement 方法并最后返回一个 ReactElement 对象给我们。
当然我们不使用 JSX,而是直接通过 React.createElement 方法来创建 ReactElement 对象也是可以的。React.createElement 方法中各个参数的含义如下:
- 第一个参数:可以是一个字符串,表示一个标准的 HTML 元素。或者是一个 ReactClass 类型的对象,表示我们之前封装好的自定义组件。
- 第二个参数:是一个对象(字典)。它保存了这个元素的所有固有属性(即传入后基本不会改变的值)。
- 从第三个参数开始:都被认作是该元素的子元素。
四、JSX使用JavaScript
在 基本语法 部分的代码体现了 JSX 的基本语法规则:遇到 HTML 标签(以 < 开头),就用 HTML 规则解析;遇到代码块(以 { 开头),就用JavaScript 规则解析。不是什么 JavaScript 语法都可以用的, 像if语句就不可以用,下面列举一些用法。其实会用最基本的用法就够了,其他的了解下。
1)、在 JSX 中使用变量1
2var name = 'test';
<div>{name + '6666'}</div>
2)、在 JSX 中使用 Array (特殊的变量)
这个方式很方便1
2
3
4
5
6
7
8var arr=[
<h1>Hello JSX one</h1>,
<h2>React is awesome</h2>,
];
ReactDom.render(
<div>{arr}</div>,
document.getElementById('root')
);
3)、在 JSX 中使用函数1
2
3
4
5
6
7
8var names = ['Felix', 'David', 'Lucy'];
<div>
{
names.map(function(item){
return <div>Hello, {item}</div>
})
}
</div>
其实就是相当于函数返回一个结果,这个结果没有绑在变量上,直接使用了。
3)、条件判断
直接使用 if 语句,目前 JSX 是不支持的,可以使用以下方法
- 使用三目运算符
- 设置一个变量并在属性中引用它
- 将逻辑转化到函数中
- 使用短路运算符
4)、在JSX中使用…操作符
…操作符是ES6新特性,JSX 使用了她的特点,但并不是真正的ES6语法。1
2
3
4var obj={};
obj.foo = x;
obj.bar = y;
var component = <Component {...obj} />
相当于1
var component = <Component foo={obj.foo} bar={obj.bar} />;
五、JSX优点和特点
- 更加熟悉, 语法跟HTML非常相似(90以上相似度)
- 更加语义化,语序自定义标间及组件。
- 更加直观,标签处理方式,更加可读
- 抽象化, React的升级不需要改动任何JSX代码
- 关键点分离,模块化, JSX以干净和简介的方式保证了组件中的标签与所有业务逻辑的互相分离。