React.js 小书 Lesson6 - 使用 JSX 描述 UI 信息
- 作者:胡子大哈
- 原文链接:http://huziketang.com/books/react/lesson6
- 转载请注明出处,保留原文链接和作者信息。
这一节我们通过一个简单的例子讲解 React.js 描述页面 UI 的方式。把 src/index.js中的代码改成:
import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import './index.css'
class Header extends Component {
render () {
return (
<div>
<h1>React 小书</h1>
</div>
)
}
}
ReactDOM.render(
<Header />,
document.getElementById('root')
)
我们在文件头部从 react 的包当中引入了 React 和 React.js 的组件父类 Component。记住,只要你要写 React.js 组件,那么就必须要引入这两个东西。
ReactDOM 可以帮助我们把 React 组件渲染到页面上去,没有其它的作用了。你可以发现它是从 react-dom 中引入的,而不是从 react 引入。有些朋友可能会疑惑,为什么不把这些东西都包含在 react 包当中呢?我们稍后会回答这个问题。
接下来的代码你看起来会比较熟悉,但又会有点陌生。你看其实它跟我们前几节里面讲的内容其实很类似,一个组件继承 Component 类,有一个 render 方法,并且把这个组件的 HTML 结构返回;这里 return 的东西就比较奇怪了,它并不是一个字符串,看起来像是纯 HTML 代码写在 JavaScript 代码里面。你也许会说,这不就有语法错误了么?这完全不是合法的 JavaScript 代码。这种看起来“在 JavaScript 写的标签的”语法叫 JSX。
JSX 原理
为了让大家深刻理解 JSX 的含义。有必要简单介绍了一下 JSX 稍微底层的运作原理,这样大家可以更加深刻理解 JSX 到底是什么东西,为什么要有这种语法,它是经过怎么样的转化变成页面的元素的。
思考一个问题:如何用 JavaScript 对象来表现一个 DOM 元素的结构,举个例子:
<div class='box' id='content'>
<div class='title'>Hello</div>
<button>Click</button>
</div>
每个 DOM 元素的结构都可以用 JavaScript 的对象来表示。你会发现一个 DOM 元素包含的信息其实只有三个:标签名,属性,子元素。
所以其实上面这个 HTML 所有的信息我们都可以用合法的 JavaScript 对象来表示:
{
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 的方式写起来就方便很多了。
于是 React.js 就把 JavaScript 的语法扩展了一下,让 JavaScript 语言能够支持这种直接在 JavaScript 代码里面编写类似 HTML 标签结构的语法,这样写起来就方便很多了。编译的过程会把类似 HTML 的 JSX 结构转换成 JavaScript 的对象结构。
上面的代码:
import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import './index.css'
class Header extends Component {
render () {
return (
<div>
<h1 className='title'>React 小书</h1>
</div>
)
}
}
ReactDOM.render(
<Header />,
document.getElementById('root')
)
经过编译以后会变成:
import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import './index.css'
class Header extends Component {
render () {
return (
React.createElement(
"div",
null,
React.createElement(
"h1",
{ className: 'title' },
"React 小书"
)
)
)
}
}
ReactDOM.render(
React.createElement(Header, null),
document.getElementById('root')
);
React.createElement 会构建一个 JavaScript 对象来描述你 HTML 结构的信息,包括标签名、属性、还有子元素等。这样的代码就是合法的 JavaScript 代码了。所以使用 React 和 JSX 的时候一定要经过编译的过程。
这里再重复一遍:所谓的 JSX 其实就是 JavaScript 对象。每当在 JavaScript 代码中看到这种 JSX 结构的时候,脑子里面就可以自动做转化,这样对你理解 React.js 的组件写法很有好处。
有了这个表示 HTML 结构和信息的对象以后,就可以拿去构造真正的 DOM 元素,然后把这个 DOM 元素塞到页面上。这也是我们最后一段代码中 ReactDOM.render所干的事情:
ReactDOM.render(
<Header />,
document.getElementById('root')
)
ReactDOM.render 功能就是把组件渲染并且构造 DOM 树,然后插入到页面上某个特定的元素上(在这里是 id 为 root 的 div 元素)。
所以可以总结一下从 JSX 到页面到底经过了什么样的过程:

有些同学可能会问,为什么不直接从 JSX 直接渲染构造 DOM 结构,而是要经过中间这么一层呢?
第一个原因是,当我们拿到一个表示 UI 的结构和信息的对象以后,不一定会把元素渲染到浏览器的普通页面上,我们有可能把这个结构渲染到 canvas 上,或者是手机 App 上。所以这也是为什么会要把 react-dom 单独抽离出来的原因,可以想象有一个叫 react-canvas 可以帮我们把 UI 渲染到 canvas 上,或者是有一个叫 react-app可以帮我们把它转换成原生的 App(实际上这玩意叫 ReactNative)。
第二个原因是,有了这样一个对象。当数据变化,需要更新组件的时候,就可以用比较快的算法操作这个 JavaScript 对象,而不用直接操作页面上的 DOM,这样可以尽量少的减少浏览器重排,极大地优化性能。这个在以后的章节中我们会提到。
总结
要记住几个点:
- JSX 是 JavaScript 语言的一种语法扩展,长得像 HTML,但并不是 HTML。
- React.js 可以用 JSX 来描述你的组件长什么样的。
- JSX 在编译的时候会变成相应的 JavaScript 对象描述。
react-dom负责把这个用来描述 UI 信息的 JavaScript 对象变成 DOM 元素,并且渲染到页面上。
课后练习题
因为第三方评论工具有问题,对本章节有任何疑问的朋友可以移步到 React.js 小书的论坛 发帖,我会回答大家的疑问。
React.js 小书 Lesson6 - 使用 JSX 描述 UI 信息的更多相关文章
- 【React.js小书】动手实现 React-redux(五):Provider - 方志
我们要把 context 相关的代码从所有业务组件中清除出去,现在的代码里面还有一个地方是被污染的.那就是 src/index.js 里面的 Index: 1234567891011121314151 ...
- React.js 小书介绍
React.js 小书 Github 关于作者 这是一本关于 React.js 的小书. 因为工作中一直在使用 React.js,也一直以来想总结一下自己关于 React.js 的一些知识.经验.于是 ...
- React.js小书总结
(迁移自旧博客2017 08 27) 第一阶段 react的组件相当于MVC里面的View. react.js 将帮助我们将界面分成了各个独立的小块,每一个块就是组件,这些组件之间可以组合.嵌套,就成 ...
- React.js 小书 Lesson21 - ref 和 React.js 中的 DOM 操作
作者:胡子大哈 原文链接:http://huziketang.com/books/react/lesson21 转载请注明出处,保留原文链接和作者信息. 在 React.js 当中你基本不需要和 DO ...
- React.js 小书 Lesson22 - props.children 和容器类组件
作者:胡子大哈 原文链接:http://huziketang.com/books/react/lesson22 转载请注明出处,保留原文链接和作者信息. 有一类组件,充当了容器的作用,它定义了一种外层 ...
- React.js 小书 Lesson18 - 挂载阶段的组件生命周期(一)
作者:胡子大哈 原文链接:http://huziketang.com/books/react/lesson18 转载请注明出处,保留原文链接和作者信息. 我们在讲解 JSX 的章节中提到,下面的代码: ...
- React.js 小书 Lesson16 - 实战分析:评论功能(三)
作者:胡子大哈 原文链接:http://huziketang.com/books/react/lesson16 转载请注明出处,保留原文链接和作者信息. 接下来的代码比较顺理成章了.修改 Commen ...
- React.js 小书 Lesson14 - 实战分析:评论功能(一)
作者:胡子大哈 原文链接:http://huziketang.com/books/react/lesson14 转载请注明出处,保留原文链接和作者信息. 课程到这里大家已经掌握了 React.js 的 ...
- React.js 小书 Lesson13 - 渲染列表数据
作者:胡子大哈 原文链接:http://huziketang.com/books/react/lesson13 转载请注明出处,保留原文链接和作者信息. 列表数据在前端非常常见,我们经常要处理这种类型 ...
随机推荐
- C#中关于换行符的记录
最近在做一个练习的时候,从其他数据库提出来数据装到自己的数据表中,发现同是编辑器的内容却在页面上显示不出来,但是在数据库中又确实存在,经过一番折腾之后发现是 换行符 的问题.在我的编辑器中是以 ‘\r ...
- 在FooterTemplate内显示DropDownList控件
如果想在Gridview控件FooterTemplate内显示DropDownList控件供用户添加数据时所应用.有两种方法可以实现,一种是在GridView控件的OnRowDataBound事件中写 ...
- Nodejs 文档概览
Node.js v8.11.1 Node.js v8.11.1 文档 今天大致浏览了一下Node.js的官方文档,走马观花的了解了大部分模块的api,对他们的使用场景做一个简单的笔记 assert 断 ...
- 【转】.net算术运算导致溢出
源地址:http://blog.csdn.net/hawksoft/article/details/70470136
- vue坑
项目地址:https://pan.baidu.com/s/1c1Dflp2 使用前提:安装nodejs环境,webpack的配置官网的例子跟着跑一遍,会vue开发 研究webpack+vue研究了一个 ...
- 解决三星官方移植的内核默认是没有打开支持V4L USB devices
在linux比较新的kernel,都标配了各类摄像头的驱动支持,不用我们自己移植驱动,只需通过make menuconfig配置内核支持我们所需的摄像头类型即可.以下是在三星官方内核中配置V ...
- 使用Tensorflow object detection API——环境搭建与测试
[软件环境搭建] 操作系统:windows 10 64位 内存:8G CPU:I7-6700 Tensorflow: 1.4 Python:3.5 Anaconda3 (64-bit) 以上环境搭建请 ...
- 17.Merge Two Binary Trees(合并两个二叉树)
Level: Easy 题目描述: Given two binary trees and imagine that when you put one of them to cover the ot ...
- zmq导致master收不到minion的key
问题: 官网方式yum安装完saltstack之后,master与minion都成功启动后,但是却发现怎么都收不到minion的key.(zmq版本不一致所致,困扰了我好几天,希望能帮到大家.) 分析 ...
- Codeforces Round #305 (Div. 2) A
Description While Mike was walking in the subway, all the stuff in his back-bag dropped on the groun ...