# JSX
前面一直提到 JSX 语法,那么JSX到底是什么?
>[success] JSX是一种 JavaScript 的语法扩展,Javascript和XML结合的一种格式。React发明了JSX,利用HTML语法来创建虚拟DOM。当遇到<,JSX就当HTML解析,遇到{就当JavaScript解析。
## 使用JSX应该注意的几点
第一, 在 JSX 中使用的“ 元素” 不局限于 HTML 中的 元素, 它可以是任何一个 React 组件,比如我们之前创建的 `Counter` 组件。
React 判断 一个元素是 HTML 元素还是 React 组件的原则就是看第一个字母是否大写, 如果在 JSX 中我们不用 `Counter` 而是用 `counter`, 那就得不到我们想要的结果。
第二, 在 JSX 中可以通过 `onClick` 这样的方式给一个元素添加一个事件处理函数, 当然, 在 HTML 中也可以用 onclick( 注意和 `onClick` 拼写有区别), 但在 HTML 中直接书写 onclick 一直就是为人诟病的写法, 网页应用开发界一直倡导的是用 jQuery 的方法添加事件处理函数, 直接写 onclick 会带来代码混乱的问题。
并不推荐在组件中直接使用 `onclick`,而是使用 `onClick`,主要是 `onclick` 有以下几个缺点:
- onclick 添加的事件处理函数是在全局环境下执行的, 这污染了全局环境, 很容易产生意料不到的后果;
- 给很多 DOM 元素添加 onclick 事件, 可能会影响网页的性能, 毕竟, 网页需要的事件处理函数越多, 性能就会越低;
- 对于使用 onclick 的 DOM 元素, 如果要动态地从 DOM 树中删掉的话, 需要把对应的时间处理器注销, 假如忘了注销, 就可能造成 内存泄露, 这样的 bug 很难被发现。
然而,在 JSX 中并不存在上述缺点。
在 JSX 中,使用 `onClick` 并不是将事件直接挂在到对应的 DOM 中,而是使用事件委托,挂在到DOM树的最顶层中,这样,无论添加多少个 `onClick` ,在DOM树中都只有一个事件处理函数,再根据具体组件分派到不同的实现方法中。
(来自 [程墨. 深入浅出React和Redux (实战) (Kindle位置276). 机械工业出版社. Kindle 版本. ](),有改动)
## 使用JSX
可以将任意DOM元素赋值到一个常量:
```jsx
const element = <h1>Hello, world!</h1>;
```
也可以创建一个嵌套的DOM树
```jsx
const element = (
<div>
<h1>Hello!</h1>
<h2>Good to see you here.</h2>
</div>
);
```
JSX 乍看起来可能比较像是模版语言,但事实上它完全是在 JavaScript 内部实现的。
也可以在JSX中使用任意js表达式,在JSX中使用js表达式需要使用一对大括号 `{}`
```js
function formatName(user) {
return user.firstName + ' ' + user.lastName;
}
const user = {
firstName: 'Harper',
lastName: 'Perez'
};
const element = (
<h1>
Hello, {formatName(user)}!
</h1>
);
```
### JSX 本身其实也是一种表达式
在编译之后,JSX 其实会被转化为普通的 JavaScript 对象。
这就意味着,其实可以在 if 或者 for 语句里使用 JSX,将它赋值给变量,当作参数传入,甚至作为函数返回值都可以:
```jsx
function getGreeting(user) {
if (user) {
return <h1>Hello, {formatName(user)}!</h1>;
}
return <h1>Hello, Stranger.</h1>;
}
```
### JSX 属性
可以使用引号来定义以字符串为值的属性
```jsx
const element = <div tabIndex="0"></div>;
```
可以使用大括号来定义以 JavaScript 表达式为值的属性
```jsx
const user = {
avatarUrl: 'http://localhost/logo.png'
}
const element = <img src={user.avatarUrl} />;
```
切记在使用大括号包裹的 JavaScript 表达式时就不要再到外面套引号了。JSX 会将引号当中的内容识别为字符串而不是表达式。
>[warning] 因为 JSX 的特性更接近 JavaScript 而不是 HTML , 所以 React DOM 使用 camelCase 小驼峰命名 来定义属性的名称,而不是使用 HTML 的属性名称。
>例如,class 变成了 className,而 tabindex 则对应着 tabIndex.
### JSX只是一个语法糖
本质上来讲,JSX 只是为 `React.createElement(component, props, ...children)` 方法提供的语法糖。
Babel 转译器会把 JSX 转换成 React.createElement() 的方法调用。
所以,以下两种写法完全相同:
```jsx
const element = (
<h1 className="greeting">
Hello, world!
</h1>
);
```
```jsx
const element = React.createElement(
'h1',
{className: 'greeting'},
'Hello, world!'
);
```
编译后返回类似于以下结构的对象:
```jsx
const element = {
type: 'h1',
props: {
className: 'greeting',
children: 'Hello, world'
}
};
```
- 简介
- 第一章 React入门
- 1.1 创建一个React项目
- 1.2 组件
- 1.3 JSX
- 1.4 eject
- 1.5 渲染
- 第二章 React组件
- 2.1 组件定义
- 2.2 数据处理
- 2.2.1 props
- 2.2.2 state
- 2.3 生命周期
- 2.3.1 装载过程
- 2.3.2 更新过程
- 2.3.3 卸载过程
- 2.4 事件处理
- 2.5 条件渲染
- 2.6 列表渲染
- 第三章 React高级
- 3.1 静态类型检查
- 3.1.1 flow
- 3.1.2 typescript
- 3.2 React Developer Tools
- 第四章 Redux状态管理
- 4.1 安装与配置
- 4.2 一个简单的计数器开始
- 4.3 Store
- 4.3.1 获取state
- 4.3.2 subscribe
- 4.4 Action
- 4.4.1 Action Creators
- 4.5 Reducer
- 4.5.1 Reducer 的拆分
- 4.6 与其他状态管理工具的对比
- 第五章 React-Router路由
- 参考资料