使用JSX描述UI信息

2017-07-24  本文已影响24人  SamDing

JSX基本原理


如果用JavaScript对象来表现一个DOM元素的结构,例如:

<div class='container' id='main'>
    <div class="title">Hello</div>
    <button>Click<button>
</div>

每个DOM元素的结构都可以用JavaScript的对象来表示,一个DOM元素包含的信息其实只有三个:标签名,属性,子元素。
因此上面的这段HTML所有的信息都可以用合法的JavaScript对象来表示:

{
    tag :'div',
    attrs: { className: 'container', id: 'main' },
    children: [
        {
            tag: 'div',
            arrts: { className: 'title' },
            children: ['Hello']
        },
        {
            tag: 'button',
            attrs: null,
            children: ['Click']
        }        
    ]
}

HTML的信息和上面这段Js传达的信息其实是一样的,只不过从长度和代码结构清晰度上,用HTML会清晰很多。
React.js把JavaScript的语法扩展了一下,编译的过程会把类似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'>使用JSX描述UI信息</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' },
          "使用JSX描述UI信息"
        )
      )
    )
  }
}

ReactDOM.render(
  React.createElement(Header, null), 
  document.getElementById('root')
);

React.createElement 会构建一个JavaScript对象来描述HTML信息,包括标签名,属性还有子元素等。所以使用React和JSX的时候一定要经过编译的过程。

有了这个HTML结构和信息的对象之后,就可以拿去构造DOM元素了,然后把这个DOM元素塞到页面里。这就是 ReactDOM.render 方法所干的事情:

ReactDOM.render(
  React.createElement(Header, null), 
  document.getElementById('root')
);

总结一下从JSX到页面呈现经历了下面的过程:

image.png

那么为什么不直接从JSX直接渲染成可供展示的DOM元素呢?

第一个原因是,当我们拿到一个表示UI的结构时,不一定会把这个元素渲染到浏览器上,也可能是手机App上,所以这也是为什么要把react-dom专门分离出来的原因。可以想象为,一个叫react-canvas的模块可以帮我们把UI渲染到浏览器上,一个叫react-native的模块帮我们把UI渲染到App上(ReactNative)。

第二个原因是,有了这样一个对象,当数据变化,需要更新Component的时候,就可以用比较快的算法(diff算法)操作这个对象,而不用直接操作页面上的DOM,这样可以尽可能少的减少浏览器重拍,极大优化性能。

总结


上一篇 下一篇

猜你喜欢

热点阅读