React中JSX原理

2020-03-07  本文已影响0人  learninginto

React中JSX原理

在vue中,我们使用render函数来构建组件的dom结构性能较高,因为省去了查找和编译模板的过程,但是在render中利用createElement创建结构的时候代码可读性较低,较为复杂,此时可以利用jsx语法来在render中创建dom,解决这个问题,但是前提是需要使用工具来编译jsx 官网链接

  1. 如要要使用 JSX 语法,而浏览器不支持JSX语法,必须先安装

    cnpm i @babel/babel-preset-react -D
    
  2. .babelrc 中添加配置;

    {
        "presets": [
            [
                "@babel/preset-env",
                {
                    "targets":{
                        "browsers":["last 2 version"]
                    }
                }
            ],
            ["@babel/preset-react"]
        ],
            "plugins":["@babel/plugin-transform-runtime"]
    }
    
  3. JSX语法的本质:还是以 React.createElement 的形式来实现的,并没有直接把用户写的HTML代码,渲染到页面上;

  4. 当编译引擎,在编译JSX代码的时候,如果遇到了<那么就把它当作 HTML代码去编译,如果遇到了 {} 就把花括号内部的代码当作普通JS代码去编译;所以,在{}内部可以写任何符合JS规范的代码;

  5. 在JSX中,如果要为元素添加class属性了,那么,必须写成className,因为 class在ES6中是一个关键字;和class类似,label标签的 for 属性需要替换为 htmlFor.

    var href="http://www.baidu.com";
    var class1 = "box"
    var dom = <a href={href} className={class1}>百度一下</a>
    <label htmlFor="username"></label>
    
  6. 在JSX创建DOM的时候,所有的节点,必须有唯一的根元素进行包裹

  7. 注释必须放到 {} 内部,eg:{/* 这是jsx中的注释 */}

import React, { Component } from 'react';

class Login extends Component {

  fullname(firstname, lastname) {
    return firstname + lastname;
  }

  render() {
    let islogin = sessionStorage.getItem('username')
    if (islogin) {
      let username = sessionStorage.getItem('username');
      return (
        <div>
          {1 + 2 + 3}
          <hr/>
         欢迎, {username}
         <hr/>
         {
           this.fullname('han','ye')
         }
        </div>
      );
    } else {
      return <h1>您还没有登录</h1>
    }

  }
}

export default Login;

要明白JSX的原理,需要先明白如何用 JavaScript 对象来表现一个 DOM 元素的结构?

<div class='app' id='appRoot'>
  <h1 class='title'>欢迎进入React的世界</h1>
  <p>
    React.js 是一个帮助你构建页面 UI 的库
  </p>
</div>

上面这个 HTML 所有的信息我们都可以用 JavaScript 对象来表示:

{
  tag: 'div',
  attrs: { className: 'app', id: 'appRoot'},
  children: [
    {
      tag: 'h1',
      attrs: { className: 'title' },
      children: ['欢迎进入React的世界']
    },
    {
      tag: 'p',
      attrs: null,
      children: ['React.js 是一个构建页面 UI 的库']
    }
  ]
}

但是用 JavaScript 写起来太长了,结构看起来又不清晰,用 HTML 的方式写起来就方便很多了。

于是 React.js 就把 JavaScript 的语法扩展了一下,让 JavaScript 语言能够支持这种直接在 JavaScript 代码里面编写类似 HTML 标签结构的语法,这样写起来就方便很多了。编译的过程会把类似 HTML 的 JSX 结构转换成 JavaScript 的对象结构。

下面JSX代码:

import React from 'react'
import ReactDOM from 'react-dom'

class App extends React.Component {
  render () {
    return (
      <div className='app' id='appRoot'>
        <h1 className='title'>欢迎进入React的世界</h1>
        <p>
          React.js 是一个构建页面 UI 的库
        </p>
      </div>
    )
  }
}

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

编译之后将得到这样的代码

import React from 'react'
import ReactDOM from 'react-dom'

class App extends React.Component {
  render () {
    return (
      React.createElement(
        "div",
        {
          className: 'app',
          id: 'appRoot'
        },
        React.createElement(
          "h1",
          { className: 'title' },
          "欢迎进入React的世界"
        ),
        React.createElement(
          "p",
          null,
          "React.js 是一个构建页面 UI 的库"
        )
      )
    )
  }
}

ReactDOM.render(
    React.createElement(App),
  document.getElementById('root')
)

React.createElement 会构建一个 JavaScript 对象来描述你 HTML 结构的信息,包括标签名、属性、还有子元素等, 语法为

React.createElement(
  type,
  [props],
  [...children]
)

所谓的 JSX 其实就是 JavaScript 对象,所以使用 React 和 JSX 的时候一定要经过编译的过程:

JSX =>使用react构造组件,bable进行编译 => JavaScript对象 => ReactDOM.render() => DOM元素 => 插入页面

上一篇下一篇

猜你喜欢

热点阅读