React源码解析18(1)------ React.createElement 和 jsx

news/2025/2/4 18:28:48/

1.React.createElement

我们知道在React17版本之前,我们在项目中是一定需要引入react的。

import React from “react”

即便我们有时候没有使用到React,也需要引入。原因是什么呢?

在React项目中,如果我们使用了模板语法JSX,我们知道它要先经过babel的转译。那babel会将JSX转换成什么样子的格式呢?

在这里插入图片描述
可以看到,现在的babel会将JSX模板转换成带有jsx方法的内容。但是在17之前,babel是将JSX转换为带有React.createElement方法的内容。

而这也是为什么在17之前我们要引入React才能让项目正常使用。

2.ReactElement元素

如果我们在项目代码中,打印一个react元素:

const jsx = <div><span>123</span></div>
console.log(jsx)

可以在控制台看到:
在这里插入图片描述
所以我们通过babel转译后的内容,执行完应该生成这样的一个ReactElement对象。
所以在实现jsx方法前,我们可以定义一个ReactElement类(实际的React源码中是一个方法,但是这里为了好看一些,使用类的结构)。

class ReactElement {constructor(key, props, ref, type) {this.$$typeof = Symbol.for('react.element')this.key = key;this.props = props;this.ref = ref;this.type = type;}
}

3.实现JSX方法

在上面的转译内容我们可以看到,jsx方法接受两个参数,第一个参数是类型:例如div,span或者自定一类型。
第二个参数是配置参数:例如class,ref等参数。

我们只需要将ref,type,key这三个属性,直接赋值给ReactElement元素。而其他的属性全部放在props里面就可以了:

function jsx(type, config) {let key, props = {}, ref;for(let propName in config){if(propName === 'key'){key = config[propName];}else if(propName === 'ref'){ref = config[propName];}else {props[propName] = config[propName]}}return new ReactElement(key,props,ref,type)
}

由于递归的过程已经被babel处理了,所以其实在jsx方法中只需要遍历即可,并不需要太过复杂的处理。

4.测试

现在我们使用babel转译过的内容,对jsx方法进行测试:

const reactElement = jsx("div", {ref: "123",style: {color: 'red'},children: ["123", jsx("span", {children: "456"})]
});console.log(reactElement)

可以在控制台看到jsx方法执行的结果:
在这里插入图片描述

以上就是通过babel处理后,react对处理的内容做的初步处理。


http://www.ppmy.cn/news/1019163.html

相关文章

docker删除容器时报错:Error response from daemon: reference does not exist

前言 之前使用的docker版本太低了&#xff0c;升级高版本docker之后的错误。 低版本docker&#xff08;1.30.1&#xff09;中的镜像有&#xff1a;golang、mysql&#xff0c;将docker升级为24.0.5并新拉取mysql最新版本之后&#xff0c;执行docker images命令&#xff0c;发现…

题目:2356.每位教师所教授的科目种类

​题目来源&#xff1a; leetcode题目&#xff0c;网址&#xff1a;2356. 每位教师所教授的科目种类的数量 - 力扣&#xff08;LeetCode&#xff09; 解题思路&#xff1a; 使用group by 分组聚合后&#xff0c;统计每组中的 subject_id 的不同个数后按要求输出即可。 解题代…

行业追踪,2023-08-09

自动复盘 2023-08-09 凡所有相&#xff0c;皆是虚妄。若见诸相非相&#xff0c;即见如来。 k 线图是最好的老师&#xff0c;每天持续发布板块的rps排名&#xff0c;追踪板块&#xff0c;板块来开仓&#xff0c;板块去清仓&#xff0c;丢弃自以为是的想法&#xff0c;板块去留让…

更优雅地调试SwiftUI—借助LLDB

更优雅地调试SwiftUI—借助LLDB 概述 你是否写过这样的代码: struct ContentView: View {@State private var mySize: CGFloat = 15.0var myString: String = "Hi LLDB"var myArray: [Int] = [1, 2, 3]var body: some View {VStack {Text("Hello World"…

Java基础入门篇——结构语句和if语句(十)

目录 一、选择结构语句 二、if条件语句 2.1 if语句 2.2 if流程图 2.3 if-else流程图 2.4 if-else if-else流程图 三、总结 一、选择结构语句 &#xff11;.什么是选择结构语句&#xff1f; 选择结构语句&#xff08;也称为条件语句&#xff09;是一种编程结构&#…

rsync同时配置delete和exclude

rsync版本: 3.2.7 在/home/test/rsyncexclude.list文件中配置 *.html 执行拉取命令&#xff1a; rsync -rtDlvzP --delete --progress --exclude-from/home/test/rsyncexclude.list lxyz192.168.1.2::lxyzbackup /home/test/lxyzdata 如果本地目录中已存在 .html 文件&…

一种简单高效的IMU姿态解算方法

这里给出一种简单高效的IMU姿态解算方法&#xff0c;本方法的特点就是思路非常的简单&#xff0c;并且效果也还可以&#xff0c;地面机器人这类运动想对不那么剧烈的应用应该是能应付的&#xff0c;但是震动较大的无人机、足式机器人等应用是否能应用还有待试验。 代码如下&am…

【APITable】教程:创建并运行一个自建小程序

1.进入APITable&#xff0c;在想要创建小程序的看板页面点击右上角的【小程序】&#xff0c;进入小程序编辑页面。 2.创建一个新的小程序区。 点击【 添加小程序】 点击创建小程序&#xff0c;选择模板&#xff0c;输入名字。 3.确定后进入小程序部署引导页面。 4.打开Xshell 7…