React中JSX原理
在vue中,我们使用render函数来构建组件的dom结构性能较高,因为省去了查找和编译模板的过程,但是在render中利用createElement创建结构的时候代码可读性较低,较为复杂,此时可以利用jsx语法来在render中创建dom,解决这个问题,但是前提是需要使用工具来编译jsx 官网链接
-
如要要使用 JSX 语法,而浏览器不支持JSX语法,必须先安装
cnpm i @babel/babel-preset-react -D
-
在
.babelrc
中添加配置;{ "presets": [ [ "@babel/preset-env", { "targets":{ "browsers":["last 2 version"] } } ], ["@babel/preset-react"] ], "plugins":["@babel/plugin-transform-runtime"] }
JSX语法的本质:还是以 React.createElement 的形式来实现的,并没有直接把用户写的HTML代码,渲染到页面上;
当编译引擎,在编译JSX代码的时候,如果遇到了
<
那么就把它当作 HTML代码去编译,如果遇到了{}
就把花括号内部的代码当作普通JS代码去编译;所以,在{}内部可以写任何符合JS规范的代码;-
在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>
在JSX创建DOM的时候,所有的节点,必须有唯一的根元素进行包裹;
注释必须放到 {} 内部,eg:
{/* 这是jsx中的注释 */}
- Demo
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 元素的结构?
- 看下面的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元素 => 插入页面