我第一次接触JSX是在学习React的时候,当时乍一看语法觉得和js很像,在一看又觉得和HTML很像,后期有了项目经验之后确定jsx确实和那两位有关系。下面解释怎么个有关系法。
一. React组件的构成?
JSX和React有什么关系呢?简单说,JSX就是方便React使视图层(View层)组件化,承载了HTML构建页面的职责。这点可以看出React还是和其他Js模板语言有着异曲同工之秒的,不同的是React致力于通过创建和更新虚拟元素来管理整个虚拟DOM的(Virtual DOM)。
那什么是虚拟元素呢,其实就是真实元素的对应,虚拟元素的创建和更新都是在内存中完成的,并不会渲染到真正DOM中。虚拟元素分为虚拟DOM和虚拟组件,对应的也就是原生DOM元素和自定义组件。
接着,从DOM元素和自定义组件来解释:
1.DOM元素
一个很普通的标签:
<button class="btn btn-blue">
<em>Confirm</em>
</button>
复制代码
上述button标签包含了元素的类型和属性,转换成JSON对象可以更清晰地看见包括元素的类型和属性,即,该标签是一个DOM元素:
{
type: 'button',
props: {
className: 'btn btn-blue',
children: {
type: 'em',
props: {
children: 'Confirm'
}
}
}
}
复制代码
2.组件元素
上面实例用自定义方法表示为:
const Button = ({color,text}) => {
return (
type: 'button',
props: {
className: `btn btn-${color}`,
children: {
type: 'em',
props: {
children: text
}
}
}
)
}
复制代码
该方法用JSON结构描述它为下述,也就是说组件方法的方法名对应了元素的类型,参数对应了元素的属性,满足了构造元素的两大必要条件(元素类型和元素属性),得出结论:自定义方法也是元素
{
type: Button,
props: {
color: 'blue',
text: 'Confirm'
}
}
复制代码
用了两个例子来说明一件事----无论普通标签还是一个自定义组件方法,都可以用元素表示。这也是React核心思想之一:因为有公共的表达方法,我们可以让元素们层层嵌套或混合,这些层层嵌套的组件元素就是所谓的React组件,最终我们可以通过递归渲染的方式渲染出一整棵DOM树。
二. JSX由来
构建一个复杂的React组件(还是一个Button组件吧)
(1).首先定义一个组件元素:
const DanderButton = ({text}) => {
type: Button,
props: {
color: 'blue',
text: text
}
}
复制代码
(2).用上面的组建继续封装一个新的组件
const DeleteButton = () => {
return (
type: 'div',
props: {
children: [
{
type: 'p',
props: {
children: 'Are you sure?'
}
},{
type: DanderButton,
props: {
children: 'Confirm'
}
},{
type: 'Button',
props: {
color: 'blue',
children: 'Cancel'
}
}
]
}
)
}
复制代码
这是一个比较简单的React组件的嵌套,DeleteButton组件清晰地表达了一个功能模块(最外侧div)、一段提示语、一个表示确认的按钮、一个表示取消的按钮,这么简单的功能都已经感觉到很繁琐了,那么如果用这种方式去编程,感觉会很糟糕,这时让我们想起了用HTML写页面的畅快,JSX写法应运而生。
同样是上面的功能,看看JSX是怎么实现的:
const DeleteButton () => (
<div>
<p>Are you sure?</p>
<DanderButton> Confirm </DanderButton>
<Buton color="blue">Cancel</Buutton>
</div>
);
复制代码
可见:JSX是将HTML语法加入到Javascript代码中,再通过翻译器转换成纯Javascript后让浏览器执行。实际开发中打包阶段都已将编译成纯Javascript代码,所以不会带来任何副作用,反而让代码更加直观并且易于维护。
现阶段为JSX语法解析的编译器基本上都在用Babel
上述代码可以被Babel解析成React可以执行的代码
var DeleteButton = function DeleteButton () {
return React.createElement(
'div',
null,
React.createElement(
...
),
React.createElement(
...
),
React.createElement(
...
)
)
}
复制代码
可以看出,创建元素时候除了使用React.createElement创建之外,其结构与JSON一样。
总结:
综合来看,JSX实质上就是为了方便React将View层组件化,通过将HTMl语法加到Javascript代码中,以承担构建页面的职责。