6

React必修技能JSX

本篇我们来了解React的JSX语法,在此之前,我们先安装React。

这里需要注意两点:

1.第一点记得安装node,地址:https://nodejs.org/en/ 使用lts版本。

2.安装脚手架,地址:https://github.com/facebookin...

步骤

1.安装脚手架

npm install -g create-react-app

2.构建项目

create-react-app hello-react

3.启动项目

输入

  cd hello-react
  yarn start

看到界面,建立样板项目完成。

build.png

注意

1.npm 有时候慢,多等会。

2.可以使用gitbash命令行,比cmd好用太多。

地址:https://gitforwindows.org/

初识JSX

在安装完毕以后让我们回到今天的主题,React的JSX语法。

我本身是很反对动不动就搞一个语言或者推倒一个东西重来的,一来是学习成本,二来是项目积淀清零。

但是我很喜欢JSX,这并不矛盾,因为它确实挺好用。

我们看看JSX到底是怎么回事。

打开App.js,删掉无用的东西变成小纯洁,模仿之前原生星星组件写法。

import React, { Component } from 'react'
import ReactDOM from 'react-dom'
class RatingStar extends Component {
  render () {
    return (
      <div id ="box">
          <h1>我是星星评分组件</h1>
      </div>
    )
  }
}

ReactDOM.render(
  <RatingStar />,
  document.getElementById('root')
)
export default RatingStar;

这里的 Component就是相当于我们自己写那个component.js,react就是实现virtualDOM什么的东西。

ReactDOM就相当于帮我们把我们要渲染的东西扔到root上面,粗略类比mounted方法(不是,但是先这么理解就好。

那么重点来了,return 小括号里面的四不像是什么?

你如果是一个字符串我能理解,你如果是一个对象我也能理解,可是你是JS里面X html 就不好理解了。

其实这个就是我们之前使用一个字符串描述一个组件。

`
<div class='starbox'>
    <span data-index="0" class=${this.state.score >= 1 ? 'on' : ''}></span>
    <span data-index="1" class=${this.state.score >= 2 ? 'on' : ''}></span>
    <span data-index="2" class=${this.state.score >= 3 ? 'on' : ''}></span>
    <span data-index="3" class=${this.state.score >= 4 ? 'on' : ''}></span>
    <span data-index="4" class=${this.state.score >= 5 ? 'on' : ''}></span>
    <strong class='score'>${this.state.score}${this.props.unit}</strong>
</div>
`

但是大家看着一点也不优雅,重点是如果我操作很多东西,字符串拼接,加上变量,如果在写if else判断,那这个字符串的通用性和可维护性几乎为0.用字符串去模拟一个组件明显太弱了。

那么用什么呢?

我看先看这段要模拟的东西。

<div id ="box">
    <h1 className="title">我是星星评分组件</h1>
</div>

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

{
  tag: 'div',
  attrs: {id: 'box'},
  children: [
    {
      tag: 'h1',
      arrts: {className: 'title'},
      children: ['我是星星评分组件']
    }
  ]
}

注意文本也是节点,但是你懂的,这么写比较反人类,我们更喜欢这样写:

<div id ="box">
    <h1>我是星星评分组件</h1>
</div>

所以facebook就把 JavaScript 的语法扩展了一下,让 JavaScript 语言能够支持这种直接在 JavaScript 代码里面编写类似 HTML 标签结构的语法,这样写起来就方便很多了。编译的过程会把类似 HTML 的 JSX 结构转换JavaScript 的对象结构。这就是大名鼎鼎的JSX。其实所谓的JSX就是 JavaScript 对象。

其实上面的JSX代码,

 render () {
    return (
      <div id ="box">
          <h1>我是星星评分组件</h1>
      </div>
    )
 }

转化为js就是:

import React, { Component } from 'react'
import ReactDOM from 'react-dom'
class RatingStar extends Component {
  render () {
    return (
     React.createElement(
        "div",
         {id:'box'},
        React.createElement(
          "h1",
          { className: 'title' },
          "我是星星评分组件"
        )
      )
    )
  }
}

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

其中 createElement(a, b, c)

第一个参数 a:表示元素的类型,比如:h1, div 等。

第二个参数 b:表示该元素上的属性,使用 JavaScript 对象方式表示。

第三个参数 c:表示该元素内部的内容,可以是文字,可以继续嵌套另外一个 React.createElement(a, b, c)

其实React.createElement 就相当于我们之前原生js里面的

const createDOMFromString = (domString) => {
    const div = document.createElement('div')
    div.innerHTML = domString
    return div
}

只不过这里用的是'createDOMFromObject',没有这个函数,我编得理解意思就好。

这里有一个个问题,为什么要用js对象模拟?而不是直接DOM操作?

1.因为操作对象先确定好变化,要比直接修改DOM性能高太多。

2.因为不是所有的东西最后都要修改DOM或者渲染到界面。

JSX语法

其实JSX就是一个语法糖,在JS里面写普通的HTML,然后生成一个可以描述UI样子的JS对象,供给react去使用。那么我们就看看JSX怎么用。

render里面使用JSX最常见的情况。

还记得我们原生写render的时候,最外层我们包了一个div,所以一样。

注意,必须要用一个外层的 JSX 元素把所有内容包裹起来。

render () {
    return (
      <div id ="box">
          <h1>我是星星评分组件</h1>
      </div>
      <div>我是其他</div>
    )
}

1559277943659.png

正确:
 <div id ="box">
    <h1>我是星星评分组件</h1>
    <div>我是其他</div>
</div>

更多的时候JSX配合JS使用,其实就是把JS扔到{}里面。

import React, { Component } from 'react'
import ReactDOM from 'react-dom'
class RatingStar extends Component {
  render () {
    const isHandsome = true;
    const Handsome = <span>彬哥长着一张盛世美颜</span>
    const noHandsome = <span> 彬哥长的天怒人怨</span>
    return (
      <div id ="box">
          <h1>我是星星评分组件</h1>
          <div>
            {1+1}  
          </div>
      </div>
    )
  }
}

ReactDOM.render(
  <RatingStar />,
  document.getElementById('root')
)
export default RatingStar;

更多情况是根据条件返回对应的输出结果,比如:

import React, { Component } from 'react'
import ReactDOM from 'react-dom'
class RatingStar extends Component {
  render () {
    const isHandsome = true;
    const Handsome = <span>彬哥长着一张盛世美颜</span>
    const noHandsome = <span> 彬哥长的天怒人怨</span>
    return (
      <div id ="box">
          <h1>我是星星评分组件</h1>
          <div>
            {isHandsome?Handsome:noHandsome}  
          </div>
      </div>
    )
  }
}
ReactDOM.render(
  <RatingStar />,
  document.getElementById('root')
)
export default RatingStar;

还有一个特别普遍的用法,JSX里面跑循环,

import React, { Component } from 'react'
import ReactDOM from 'react-dom'
class RatingStar extends Component {
  render() {
    const arrGood = ['高', '富', '帅'];
    const listItem = arrGood.map((good,index) =>
      <li key={index}>
        {good}
      </li>
    );
    return (
      <div id="box">
          <ul>{listItem}</ul>
      </div>
    )
  }
}

ReactDOM.render(
  <RatingStar />,
  document.getElementById('root')
)
export default RatingStar;

会这些就够用了。

就记住一点就行,在JSX内写JS,需要{}包起来。

在后面遇到JSX和ES6和组件中传递数据等结合的使用,容易跟解构析构混淆,但是大家记住上面的东西就不会出错了。

结语:

我们来回顾下,做个总结:

  1. JSX 是 JavaScript 语言的一种语法扩展,长得像 HTML,但并不是 HTML。
  2. JSX是用来描述你的组件长什么样的。
  3. JSX 在编译的时候会变成相应的 JavaScript 对象描述。
  4. react-dom 负责把这个用来描述 UI 信息的 JavaScript 对象变成 DOM 元素,并且渲染到页面上。
  5. JSX中JS代码的应用的规则。

彬哥头发多
4.3k 声望1.4k 粉丝

一个会写代码的职业规划师,2本职业规划书作者。争取未来1年帮100个朋友薪资上涨50%。