在 React 中为什么要用JSX?
起因
大家好,我是爱吃鱼的桶哥Z。相信使用React开发的童鞋,在编写组件的过程中接触最多的就是JSX。那么为什么React要用JSX来编写组件呢?JSX的本质是什么?是不是只有React才能用JSX?针对这几个问题,今天我们就一起来学习一下吧。
JSX
JSX在官网的解释是:它是一种JavaScript语法的扩展,并且它具有JavaScript的所有特性。如果有人问你为什么React中要使用JSX,其实本质是问你为什么不用其它的方案来实现,为什么偏偏是JSX?
首先,我们在前面也了解到JSX本质是JavaScript的语法扩展;其次,在React的开发中,React并不是强制要求一定要使用JSX,我们完全可以通过React.createElement来创建React组件,类似下面这样:
render() {
return React.createElement(
"div",
null,
"Hello ",
this.props.name
);
}
而我们通过JSX编写的组件,相对React.createElement来说就要简洁明了许多,同样的组件,编写起来会更为简洁,并且代码的层次也会更加的清晰,类似下面这样:
render() {
return <div>Hello {this.props.name}</div>;
}
当我们使用JSX将组件编写完成后,React内部需要将组件转化为DOM树,看起来就像XML一样。而XML在树结构的描述上天生就具有可读性强的优势。
虽然我们是通过JSX来编写组件,但是最终React还是会通过babel将JSX编译为js可执行的代码。我们之所以不直接用React.createElement来创建组件,在前面也已经说明了原因,这里就不做赘述了。
因为我们知道最终的代码会通过babel编译成js可直接执行的代码,因此JSX不仅能在React中进行使用,同样在Vue中也可以使用JSX来编写组件。并且使用JSX编写的组件也可以用于跨端应用的渲染,例如React-Native中使用的组件结构跟React结构是一样的。
扩展
在上面我们介绍了JSX最终会通过babel编译为js可执行的代码,那么Babel是如何实现JSX到js的编译呢?我们可以通过查看相关的源码来了解一下,源码如下:
module.exports = function (babel) {
var t = babel.types;
return {
name: "custom-jsx-plugin",
visitor: {
JSXElement(path) {
var openingElement = path.node.openingElement;
var tagName = openingElement.name.name;
var args = [];
args.push(t.stringLiteral(tagName));
var attribs = t.nullLiteral();
args.push(attribs);
var reactIdentfier = t.identifier("React");
var createElementIdentifier = t.identifier("createElement");
var callee = t.memberExpression(reactIdentfier, createElementIdentifier);
var callExpression = t.callExpresion(callee, args);
callExpression.arguments = callExpression.arguments.concat(path.node.children);
path.replaceWith(callExpression, path.node);
},
},
};
}
最后
我们通过学习了解到React中选用JSX的原因,以及JSX的本质是什么,也了解到babel是如何将JSX编译为js可执行的代码。如果你对babel的编译有兴趣,可以到babel官方网站进行查看和学习。
最后,如果这篇文章有帮助到你,❤️关注+点赞❤️鼓励一下作者,谢谢大家
转载自:https://juejin.cn/post/7132472958051680287