React学习笔记-JSX

React学习笔记-JSX

引入

首先,先来看一段非常简单的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import React, { Component } from 'react'
import ReactDOM from 'react-dom'

class Header extends Component {
render () {
return (
<div>
<h1>React 笔记</h1>
</div>
)
}
}

ReactDOM.render(
<Header />,
document.getElementById('root')
)

还有这个:

1
const element = <h1>Hello, world!</h1>;

一开始看完我是感觉有点奇怪的,这么粗暴地直接在 js 上直接嵌入 HTML 吗?好的,事实证明我这么简单粗暴的看法也是错的,这其实是一种JavaScript 的语法扩展,称为 JSX,这确实很容易让人联想到模板语言,但是它具有JavaScript的全部功能。那么接下来就来看看JSX的原理。

JSX 原理

事实上:所谓的 JSX 其实就是 JavaScript 对象。我们可以思考类似上面的那段 JSX 用JavaScript对象应该怎么表示:

1
2
3
4
<div class='box' id='content'>
<div class='title'>Hello</div>
<button>Click</button>
</div>

所有的信息我们都可以用合法的 JavaScript 对象来表示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
tag: 'div',
attrs: { className: 'box', id: 'content'},
children: [
{
tag: 'div',
arrts: { className: 'title' },
children: ['Hello']
},
{
tag: 'button',
attrs: null,
children: ['Click']
}
]
}

嘻嘻嘻,,发现了没有,HTML 的信息和 JavaScript 所包含的结构和信息其实是一样的,我们可以用 JavaScript 对象来描述所有能用 HTML 表示的 UI 信息。但是用 JavaScript 写起来太长了,结构看起来又不清晰,用 HTML 的方式写起来就方便很多了。

因此,把JavaScript 的语法扩展一下,让JavaScript语言能支持编写类似HTML标签结构的语法,这样会方便很多,在编译过程会把JSX结构转换成JavaScript的对象结构。
可以总结一下从JSX到页面经过什么样的过程:

那么问题又来啦,为什么不直接把JSX直接渲染成构造DOM结构呢,而要经过中间那一层呢?

第一个原因是:我们拿到的这个表示UI的结构和信息的对象后不一定会把元素直接渲染到浏览器的普通页面上,例如我们转换成原生的APP(React Native可以开发原生APP);

第二个原因是:我们都知道直接操作DOM的开销太大了,太频繁地操作DOM势必会影响性能,那么如果有一个JavaScript对象后,当数据变化时或者需要更新组件是,就可以用比较快的算法操作js对象而不是直接页面的DOM,尽量少的减少浏览器重排,极大地优化性能。

JSX的使用

在 JSX 中嵌入表达式

  1. 在JSX中使用变量,需要用大括号将其包裹起来:
1
2
const name = 'Yanzery';
const element = <h1>Hello, {name}</h1>;
  1. 可以在大括号内放置任何有效的 JavaScript 表达式。例如,2 + 2,user.firstName。
  2. JSX 也是一个表达式。例如,可以在 if 语句和 for 循环的代码块中使用 JSX,将 JSX 赋值给变量,把 JSX 当作参数传入,以及从函数中返回 JSX。
  3. 使用 JSX 指定子元素。假如一个标签里面没有内容,你可以使用 /> 来闭合标签,就像 XML 语法一样;同时JSX 标签里能够包含很多子元素:
1
2
3
4
5
6
7
8
const element = <img src={user.avatarUrl} />;

const element = (
<div>
<h1>Hello!</h1>
<h2>Good to see you here.</h2>
</div>
);

另外哦:

可以安全地在 JSX 当中插入用户输入内容,因为React DOM 在渲染所有输入内容之前,默认会进行转义。它可以确保在你的应用中,永远不会注入那些并非自己明确编写的内容。所有的内容在渲染之前都被转换成了字符串。这样可以有效地防止 XSS(cross-site-scripting, 跨站脚本)攻击。

在JSX元素中直接添加事件绑定

在HTML中直接书写onclick一直就是为人诟病的写法,网页应用开发界一
直倡导的是用jQuery的方法添加事件处理函数,直接写onclick会带来代码混
乱的问题。但是!,不得不承认直接添加事件绑定实在是太方便啦~

那么你发现没有,在JSX中同样也可以通过onClick这样的方式给一个元素添加一个事件处理函数,这是时代倒退了还是进步了呢?实际上呢,JSX的onClick事件处理方式和HTML的onclick有很大不同的哦!

即使现在,我们还是要说在HTML中直接使用onclick很不专业,原因如
下:

  • onclick添加的事件处理函数是在全局环境下执行的,这污染了全局环
    境,很容易产生意料不到的后果;

  • 给很多DOM元素添加onclick事件,可能会影响网页的性能,毕竟,网页需要的事件处理函数越多,性能就会越低;

  • 对于使用onclick的DOM元素,如果要动态地从DOM树中删掉的话,需
    要把对应的时间处理器注销,假如忘了注销,就可能造成内存泄露,这样的
    bug很难被发现。

然而在上面说的这些问题,在JSX中都不存在。

  1. onClick挂载的每个函数,都可以控制在组件范围内,不会污染
    全局空间。
  2. onClick,实际上是使用了事件委托的方式处理点击事件,无论有多少个onClick出现,其实最后都只在DOM树上添加了一个事件处理函数,挂在最顶层的DOM节点上。所有的点击事件都被这个事件处理函数捕获,然后根据具体组件分配给特定函数,使用事件委托的性能当然要比为每个onClick都挂载一个事件处理函数
    要高。
  3. React控制了组件的生命周期,在unmount的时候自然能够清除相关
    的所有事件处理函数,内存泄露也不再是一个问题。

React的组件可以把JavaScript、HTML和CSS的功能在一个文件
中,实现真正的组件封装【只是没有像vue.js那么明显,小声逼逼,我还是爱Vue的】

参考:【非常感谢!】

react官方中文文档

react.js小书

深入浅出React和Redux