认识
一、认识
当 Facebook
第一次发布 React
时,他们还引入了一种新的 JS
方言 JSX
,将原始 HTML
模板嵌入到 JS
代码中。JSX
代码本身不能被浏览器读取,必须使用Babel
和webpack
等工具将其转换为传统的JS
。
在 React.js 17
之前, 应用程序通过 @babel/preset-react
将 JSX
语法转换为 React.createElement
的 js
代码,因此需要显式将 React
引入,才能正常调用 createElement
。React.js 17
版本之后,官方与 babel
进行了合作,直接通过将 react/jsx-runtime
对 jsx
语法进行了新的转换而不依赖 React.createElement
, 称为 Runtime Automatic
(自动运行时)。在自动运行时模式下,JSX
会被转换成新的入口函数,import {jsx as _jsx} from 'react/jsx-runtime';
和 import {jsxs as _jsxs} from 'react/jsx-runtime';
。
React
中的 createElement
以及 JSX
都会返回一个 ReactElement
对象, 作为虚拟 DOM
来使用, 用于后续创建 Fiber
对象。
由上所述, React
是纯运行时前端框架, ReactElement
虚拟 DOM
结构已经在运行前编译完成, 在运行中没有机会进行编译优化。
二、编译
2.1 React.js 17.0 之后
React.js 17.0
之后 的 JSX
编译方式为 ['@babel/plugin-transform-react-jsx', { runtime: 'automatic' }]
, automatic
方式自动引入 jsx
方法, 并且将 JSX
转化为 jsx
函数。
Element
import { jsx as _jsx } from "react/jsx-runtime";
const App = /*#__PURE__*/_jsx("div", {
className: "page-app",
children: "Hello World"
});
Class Component
import { jsx as _jsx } from "react/jsx-runtime";
class App {
render() {
return /*#__PURE__*/_jsx("div", {
className: "page-app",
children: "Hello World"
});
}
}
Function Component
import { jsx as _jsx } from "react/jsx-runtime";
function App() {
return /*#__PURE__*/_jsx("div", {
className: "page-app",
children: "Hello World"
});
}
export default App;
2.1 React.js 17.0 之前
React.js 17.0 之前
的 JSX
编译方式为 ['@babel/plugin-transform-react-jsx', { runtime: 'classic' }]
, classic
方式只是将将 JSX
转化为 React.createElement
函数。
Element
const App = /*#__PURE__*/React.createElement("div", {
className: "page-app"
}, "Hello World");
Class Component
class App {
render() {
return /*#__PURE__*/React.createElement("div", {
className: "page-app"
}, "Hello World");
}
}
Function Component
function App() {
return /*#__PURE__*/React.createElement("div", {
className: "page-app"
}, "Hello World");
}
三、问题
3.1 Vue Template VS React JSX
React JSX
: React
是纯运行时前端框架, 没有机会进行编译优化。React
借助 Babel
与 @babel/plugin-transform-react-jsx
得到包含 jsx
函数的解析结果, jsx
函数用于生成 React.Element
。
Vue Template
: Vue Template
同时支持编译时 + 运行时, 在模版编译的时候可以进行非常好的性能优化, 比如: 动态标记、静态节点提升等。 Vue Template
是通过 Vue
自身实现的编译器解析, 最终生成 render
函数, render
函数内部通过 h
函数生成 VNode
虚拟节点。