React源码详细解读(一):实现解析JSX

本文介绍了React18中的JSX模板语法,展示了如何使用Babel将JSX转换为JavaScript对象并生成虚拟DOM。讲解了从React16.x到17.x版本的jsx方法变化,以及jsx模板的组成部分和用途。
摘要由CSDN通过智能技术生成

本篇react教程是基于React18版本,对应的代码在gitee上

一、简单介绍JSX

jsx是React的模板语法,允许你在JavaScript代码中写类似HTML的代码。
jsx的使用方法,类似于在javaScript里直接编写HTML,在打包的时候@babel/plugin-transform-react-jsx会将jsx语法其解析为js对象。

下面这个是jsx模板语法:

function App() {
  return <h1 class="test" key="122" >Hello World</h1>;
}

打包的时候会使用@babel/plugin-transform-react-jsx插件将jsx模板语法转为类object对象,下面分别是16.x和17.x使用babel打包后的结果。
react 16.x之前每一个jsx模板文件,都必须声明React,然后React会调用createElement方法将jsx语法最转化为虚拟dom:

React.createElement("h1", null, "hello", React.createElement("span", {
  style: {
    color: 'red'
  }
}, "world"));

react 17.x之后每一个jsx模板文件了就不用声明import React from “react”,而是直接调用react/jsx-runtime将其转化为虚拟dom:

import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
_jsxs("h1", {
  children: ["hello", _jsx("span", {
    style: {
      color: 'red'
    },
    children: "world"
  })]
});

无论是使用jsx还是createElement方法,它们的本质作用都是将jsx模板转为虚拟dom。这个对象主要有以下几个组成属性$$typeof、type、key、ref、props。如下图是转化后的虚拟dom结构:
在这里插入图片描述

二、简单实现jsx方法

我们只实现17.x的jsx方法。
前面我们已经理解了,jsx方法的作用就是将jsx模板语法转为虚拟dom的结构。

import hasOwnProperty from 'shared/hasOwnProperty';
import { REACT_ELEMENT_TYPE } from 'shared/ReactSymbols';
const RESERVED_PROPS = {
  key: true,
  ref: true,
  __self: true,
  __source: true
}
function hasValidKey(config) {
  return config.key !== undefined;
}
function hasValidRef(config) {
  return config.ref !== undefined;
}
function ReactElement(type, key, ref, props) {
  return {//这就是React元素,也被称为虚拟DOM
    $$typeof: REACT_ELEMENT_TYPE,
    type,//h1 span
    key,//唯一标识
    ref,//后面再讲,是用来获取真实DOM元素
    props//属性 children,style,id
  }
}
export function jsxDEV(type, config) {
  debugger
  let propName;//属性名
  const props = {};//属性对象
  let key = null;//每个虚拟DOM可以有一个可选的key属性,用来区分一个父节点下的不同子节点
  let ref = null;//引入,后面可以通过这实现获取真实DOM的需求
  if (hasValidKey(config)) {
    key = config.key;
  }
  if (hasValidRef(config)) {
    ref = config.ref;
  }
  for (propName in config) {
    if (hasOwnProperty.call(config, propName)
      && !RESERVED_PROPS.hasOwnProperty(propName)
    ) {
      props[propName] = config[propName]
    }
  }
  return ReactElement(type, key, ref, props);
}

对于React源码来说,我们先记住,jsx模板语法转化为虚拟dom,后会将虚拟dom生成fiber进行处理。
去运行一下我的代码,可能理解更加深入。

三、总结

  • 用户编写jsx模板语法
  • 打包时使用babel解析jsx模板语法
  • 解析后的代码,功能是,使用jsx方法进行调用,生成虚拟dom

下一篇我们开始学习fiber结构

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值