转换结果如下:
const element = React.createElement("div",{ className: "container" },"Hello, world!");
从React 17开始,引入了新的JSX转换功能,称为"Runtime Automatic"(自动运行时) 。这意味着在使用JSX语法时,不再需要手动引入React库 。在自动运行时模式下,JSX会被转换成新的入口函数,import {jsx as _jsx} from 'react/jsx-runtime'; 和 import {jsxs as _jsxs} from 'react/jsx-runtime'; 。
转换结果如下:
import { jsx as _jsx } from "react/jsx-runtime";const element = _jsx("div", {className: "container",children: "Hello, world!" });
接下来我们就来实现jsx方法或React.createElement方法(包括dev、prod两个环境) 。
工作量包括:
- 实现jsx方法
- 实现打包流程
- 实现调试打包结果的环境
- React.createElement方法
- jsxDEV方法(dev环境)
- jsx方法(prod环境)
/** ** @param type 元素类型 * @param config 元素属性,包括key,不包括子元素children * @param maybeChildren 子元素children * @returns 返回一个ReactElement */const createElement = (type: ElementType,config: any,...maybeChildren: any) => {// reactElement 自身的属性let key: Key = null;let ref: Ref = null;// 创建一个空对象props,用于存储属性const props: Props = {};// 遍历config对象,将ref、key这些ReactElement内部使用的属性提取出来,不应该被传递下去for (const prop in config) {const val = config[prop];if (prop === 'key') {if (val !== undefined) {key = '' + val;}continue;}if (prop === 'ref') {if (val !== undefined) {ref = val;}continue;}// 去除config原型链上的属性,只要自身// 一般使用{...props}将所有属性都传递下去,所以摘除ref、key属性外需要被保存到props中if ({}.hasOwnProperty.call(config, prop)) {props[prop] = val;}}const maybeChildrenLength = maybeChildren.length;if (maybeChildrenLength) {// [child] [child, child, child]if (maybeChildrenLength === 1) {props.children = maybeChildren[0];} else {props.children = maybeChildren;}}return ReactElement(type, key, ref, props);};
注意:React.createElement方法和jsx方法的区别这里只体现在第三个参数上 。实现jsx方法从React 17之后,JSX转换应用的是jsx方法,下面是它的实现:
/** ** @param type 元素类型 * @param config 元素属性 * @param maybeKey 可能的key值 * @returns 返回一个ReactElement */const jsx = (type: ElementType, config: any, maybeKey: any) => {// 初始化key和ref为空let key = null;let ref = null;// 创建一个空对象props,用于存储属性const props: Props = {};// 遍历config对象,将ref、key这些ReactElement内部使用的属性提取出来,不应该被传递下去for (const prop in config) {const val = config[prop];if (prop === "key") {continue;}if (prop === "ref") {if (val !== undefined) {ref = val;}continue;}// 一般使用{...props}将所有属性都传递下去,所以摘除ref、key属性外需要被保存到props中if ({}.hasOwnProperty.call(config, prop)) {props[prop] = val;}}// 将 maybeKey 添加到 key 中if (maybeKey !== undefined) {key = "" + maybeKey;}return ReactElement(type, key, ref, props);};
这段代码定义了一个jsx函数,主要用于创建React元素 。首先,它会提取可能存在的key和ref属性,并将剩余属性添加到一个新的props对象中 。最后用ReactElement函数创建一个React元素并返回 。从上面代码中可以看到还实现了ReactElement方法:
// jsx-runtime.jsconst supportSymbol = typeof Symbol === 'function' && Symbol.for;// 为了不滥用 React.elemen,所以为它创建一个单独的键// 为React.element元素创建一个 symbol 并放入到 symbol 注册表中export const REACT_ELEMENT_TYPE = supportSymbol? Symbol.for('react.element'): 0xeac7;export const ReactElement = function (type, key, ref, props) {const element = {$$typeof: REACT_ELEMENT_TYPE,type,key,ref,props,_mark: 'lsh',};return element;};export const jsx =...
用自己实现的的jsx接入Demo我们试着把自己实现的jsx方法,创建一个ReactElement,看它是否能够渲染在页面上 。文章插图
实现jsx方法
jsx-Demo运行地址
jsx方法和createElement的区别jsx函数和createElement函数都用于在React中创建虚拟DOM元素,但它们的语法和用法有所不同 。jsx函数来自于React 17及更高版本中的新的JSX转换功能,称为"Runtime Automatic" 。
推荐阅读
- 速看!你正在犯的七个电子邮件安全错误
- 如何实现OT网络安全?
- 人工智能如何为数据中心团队带来新的日常工作
- 永远不要在你的 Linux 系统上运行这些命令
- 数据科学家的开源社区分析指南
- ChatGPT将彻底改变人们的工作方式
- 从公司50亿参数AI绘画模型简单了解宅男AI小姐姐的生成模型
- 宋慧乔的花期好长,她做对了什么?
- 探访和田夜市:让人流连忘返的新疆味道
- 比亚迪秦PLUS DM-i|重读《职场动物进化手册》,回顾20年社会职场的艰难