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好用太多。
初识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和组件中传递数据等结合的使用,容易跟解构析构混淆,但是大家记住上面的东西就不会出错了。
结语:
我们来回顾下,做个总结:
- JSX 是 JavaScript 语言的一种语法扩展,长得像 HTML,但并不是 HTML。
- JSX是用来描述你的组件长什么样的。
- JSX 在编译的时候会变成相应的 JavaScript 对象描述。
- react-dom 负责把这个用来描述 UI 信息的 JavaScript 对象变成 DOM 元素,并且渲染到页面上。
- JSX中JS代码的应用的规则。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。