React实战学习必经之路JSX语法2

9次阅读

共计 4416 个字符,预计需要花费 12 分钟才能阅读完成。

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

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

注意

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>
    )
}

正确:
 <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 代码的应用的规则。

正文完
 0