React.js 小书 Lesson6 - 使用 JSX 描述 UI 信息


React.js 小书 Lesson6 - 使用 JSX 描述 UI 信息

本文做者:胡子大哈
本文原文:http://huziketang.com/books/react/lesson6javascript

转载请注明出处,保留原文连接以及做者信息css

在线阅读:http://huziketang.com/books/reacthtml


这一节咱们经过一个简单的例子讲解 React.js 描述页面 UI 的方式。把 src/index.js 中的代码改为:java

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 组件,那么就必需要引入这两个东西。react

ReactDOM 能够帮助咱们把 React 组件渲染到页面上去,没有其它的做用了。你能够发现它是从 react-dom 中引入的,而不是从 react 引入。有些朋友可能会疑惑,为何不把这些东西都包含在 react 包当中呢?咱们稍后会回答这个问题。算法

接下来的代码你看起来会比较熟悉,但又会有点陌生。你看其实它跟咱们前几节里面讲的内容其实很相似,一个组件继承 Component 类,有一个 render 方法,而且把这个组件的 HTML 结构返回;这里 return 的东西就比较奇怪了,它并非一个字符串,看起来像是纯 HTML 代码写在 JavaScript 代码里面。你也许会说,这不就有语法错误了么?这彻底不是合法的 JavaScript 代码。这种看起来“在 JavaScript 写的标签的”语法叫 JSX。canvas

JSX 原理

为了让你们深入理解 JSX 的含义。有必要简单介绍了一下 JSX 稍微底层的运做原理,这样你们能够更加深入理解 JSX 究竟是什么东西,为何要有这种语法,它是通过怎么样的转化变成页面的元素的。浏览器

思考一个问题:如何用 JavaScript 对象来表现一个 DOM 元素的结构,举个例子:app

<div class='box' id='content'>
  <div class='title'>Hello</div>
  <button>Click</button>
</div>

每一个 DOM 元素的结构均可以用 JavaScript 的对象来表示。你会发现一个 DOM 元素包含的信息其实只有三个:标签名,属性,子元素。less

因此其实上面这个 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 会构建一个对象里描述你 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 为 rootdiv 元素)。

因此能够总结一下从 JSX 到页面到底通过了什么样的过程:

示例图片

有些同窗可能会问,为何不直接从 JSX 直接渲染构造 DOM 结构,而是要通过中间这么一层呢?

第一个缘由是,当咱们拿到一个表示 UI 的结构和信息的对象之后,不必定会把元素渲染到浏览器的普通页面上,咱们有可能把这个结构渲染到 canvas 上,或者是手机 App 上。因此这也是为何会要把 react-dom 单独抽离出来的缘由,能够想象有一个叫 react-canvas 能够帮咱们把 UI 渲染到 canvas 上,或者是有一个叫 react-app 能够帮咱们把它转换成原生的 App(实际上这玩意叫 ReactNative)。

第二个缘由是,有了这样一个对象。当数据变化,须要更新组件的时候,就能够用比较快的算法操做这个 JavaScript 对象,而不用直接操做页面上的 DOM,这样能够尽可能少的减小浏览器重排,极大地优化性能。这个在之后的章节中咱们会提到。

总结

要记住几个点:

  1. JSX 是 JavaScript 语言的一种语法扩展,长得像 HTML,但并非 HTML。

  2. React.js 能够用 JSX 来描述你的组件长什么样的。

  3. JSX 在编译的时候会变成相应的 JavaScript 对象描述。

  4. react-dom 负责把这个用来描述 UI 信息的 JavaScript 对象变成 DOM 元素,而且渲染到面上。

下一节中咱们将介绍《React.js 小书 Lesson7 - 组件的 render 方法》

相关文章
相关标签/搜索