React源码(一): render createElement

news2024/10/6 14:30:05

React源码——渲染(render && createElement)的简单实现

前言

当前市面上公司对React需求越来越大主, 对于React的源码学习必须提上日程

初始化项目

  1. React脚手架创建项目

    • 全局安装npm install -g create-react-app
    • 创建项目create-react-app My-React-App
    • 删除不需要的文件
  2. 目录文件如下
    在这里插入图片描述

  3. 运行热更新报错,解决方案React v17 热刷新 不起作用, 或者在package.json的脚本中加上 "start": "FAST_REFRESH=false react-scripts start",
    在这里插入图片描述

react创建以及分析创建虚拟dom,babel转化的原理babel试一试

  1. Jsx----->babel----->js方法------>React.createElement()------->vdom
    在这里插入图片描述

  2. React.createElement实现

// react.js
import get$$Type from './stants';

 /* @param type 元素类型
 * @param props 元素的配置对象
 * @param children 元素的子元素们
 */
function createElement(type,props,children){
    const { key, ref, ...resprops } = props ? props : {};
    const len = arguments.length;
    if(len > 3){
        // 多个children
        resprops.children = Array.prototype.slice.call(arguments,2)
    } else if(len === 3)r
        // children
        resprops.children = children;
    }else{
        // 没有children
        // do nothing
    }
    
    return {
        $$typeof:get$$Type(type),
        key,
        ref,
        type,
        props: resprops
    }
}

const React = {
    createElement
}

export default  React
// stants.js
const REACT_TEXT = Symbol("react.TEXT");
const REACT_ELEMENT = Symbol("react.element");
const get$$Type = (type) =>{
    return type ? REACT_ELEMENT : REACT_TEXT;
}
export default get$$Type

编写reactDOM.render方法,实现想虚拟dom转化成真实的dom

  1. vdom转化成真实dom
  2. 给真实dom赋值属性
  3. 递归childrenDom
  4. 内容append到对应的容器
// react-dom.js
// 渲染真是dom到页面
function render(vdom,container){
    const reldom = createDom(vdom);
    container.appendChild(reldom)
}

// 处理函数式组件
const mountFunctionComponent = (vdom) => {
    const { type ,props } = vdom;
    // 获取到函数的vdom
    let functionVdom = type(props);
    return createDom(functionVdom)
}

// 初始化以及更新属性
const updateOtherProps = (relDom,oldProps,newProps) => {
    if(newProps){
        for(let key in newProps){
            if(key === 'style'){
                for(let k in newProps[key]){
                    relDom.style[k] = newProps[key][k]
                }
            } else {
                relDom[key] = newProps[key]
            }
        }
    }
        
    // 更新处理
    if(oldProps){
        // 旧得属性在新的属性中没有删除
        for(let key in oldProps){
            if(!newProps[key]){
                relDom[key] = null
            }
        }
    }
}

const createDom = (vdom) => {
    let relDom;
    // 纯文本
    if(!vdom?.type){
        return document.createTextNode(vdom);
    }

    // ReactFragment 
    if( typeof vdom?.type === 'symbol'){
        return document.createTextNode(vdom?.props?.children);
    }
    const { type, props: { children,...resProps } } = vdom;

    // 函数组件
    if(typeof type == 'function') {
        // functionComponent---> 变成vdom
        return mountFunctionComponent(vdom)
    } else {
        // dom 节点
        relDom = document.createElement(type);
    }

    // 赋值属性
    if(resProps){
        updateOtherProps(relDom,{},resProps)
    }

    // 递归childrenDom
    if(children){
        renderChildren(children,relDom);
    }
    return relDom;
}


const renderChildren = (children,dom) => {
        // 多个children
        if(Array.isArray(children)){
            for(let index in children){
                render(children[index],dom)
            }
        } else {
            render(children,dom)
        }
}

const ReactDom = { render }
export default ReactDom


使用

import React from './react';
import ReactDOM from './react-dom';
import './index.css';

const  App = 
<div className='app' key='app' style={{ color:'peru',background:'mediumpurple' }}>
    <span style={{ color:'yellow' }}>
    app<b style={{ color:'plum' }}>7777</b>
    </span>
    <h3 style={{ color:'orange' }}>111</h3>
    <span style={{ color:'ghostwhite' }}>apps</span>
    333
    <>6666</>
</div>;
ReactDOM.render(App, document.getElementById('root'));

效果

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/71610.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Web大学生网页作业成品——仿腾讯游戏官网网站设计与实现(HTML+CSS+JavaScript)

&#x1f389;精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业…

常规构件的立面CAD图案绘制

今天绘制的这个常规构件CAD立面图形呢&#xff0c;用到的都是很基础的CAD命令&#xff0c;有直线、修剪、倒角和旋转等&#xff0c;绘制出来也是很简单的&#xff0c;可以跟着一起操作一下 目标对象 操作步骤 1.使用直线命令绘制出一下线段&#xff0c;形成一个封闭图形 2.用…

【Windows基础】本地安全策略

本地安全策略基本内容 概念 对登陆到计算机上的账号定义一些安全设置&#xff0c;在没有活动目录集中管理的情况下&#xff0c;本地管理员必须为计算机进行设置以确保其安全。 主要是对登录到计算机得账户进行一些安全设置主要影响是本地计算机安全设置 打开方式 三种方式&…

python的distutils、setuptools模块

python中安装包的方式有很多种&#xff1a; 源码包&#xff1a;python setup.py install在线安装&#xff1a;pip install 包名&#xff08;linux&#xff09; / easy_install 包名(window) python包在开发中十分常见&#xff0c;一般的使用套路是所有的功能做一个python模块包…

一个bug,干倒一家估值1.6亿美元的公司

本文首发自「慕课网」&#xff0c;想了解更多IT干货内容&#xff0c;程序员圈内热闻&#xff0c;欢迎关注&#xff01; 动态类型一时爽&#xff0c;代码重构火葬场。 ——题记 你生涯中写过的最严重的bug是什么&#xff1f; 我们日常接触的bug&#xff0c;无非是页面崩溃&a…

【Zookeeper】学习笔记(一)

Zookeeper学习笔记一、概述1.1、Zookeeper1.2、Zookeeper工作机制1.3、Zookeeper特点1.4、数据结构1.6、应用场景1.6.1、统一命名服务1.6.2、统一配置管理1.6.3、统一集群管理1.6.4、服务器动态上下线1.6.5、软负载均衡二、下载安装2.1、集群规划2.1、集群规部署三、zk选举3.1、…

A-Level商务例题解析及练习

今日知识点&#xff1a; Marketing mix Place Price Promotion Product例题 Q: Discuss the best ways a car manufacturer could use the marketing mix to increase its share of the market. (20)解析 Answers could include: Marketing mix as a framework/process for ide…

基于RFID的物流智能仓储系统的研究(基于STM32的智能仓储系统)

提示&#xff1a;记录做的毕设 文章目录前言一、功能要求:二、代码思路三、硬件说明四、部分代码以及框图等资料五、联系我喜欢请点赞哦&#xff01;前言 随着经济的发展&#xff0c;对企业的生产经营要求提高&#xff0c;企业必须综合利用各种先进技术&#xff0c;在网络与信…

VUE3 响应式 API 之 toRef 与 toRefs

相信各位开发者看到这里时&#xff0c;应该已经对 ref 和 reactive API 都有所了解了&#xff0c;为了方便开发者使用&#xff0c; Vue 3 还推出了两个与之相关的 API &#xff1a; toRef 和 toRefs &#xff0c;都是用于 reactive 向 ref 转换。 各自的作用 这两个 API 在拼写…

Java安全--CC1的补充和CC6

CC1的补充 上一次讲的是cc链的一种形式&#xff0c;这个补充的cc链子是yso的cc链。 这个链子确实比较麻烦&#xff0c;但是和我们下一步要学习的cc6有比较紧的联系。所以做一下补充&#xff0c;值得一提的是这个链子也确实很巧妙 我们看一下两条链子的分歧在哪里&#xff1a; 从…

[附源码]Python计算机毕业设计Django影评网站系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

在地图上基于OpenLayers实现点/线/面静态的绘制显示

在做GIS相关的工作过程中&#xff0c;是离不开矢量的数据的。矢量作为最基础的数据形式&#xff0c;一般通用在各个项目中。在导航软件开发或者应用中&#xff0c;点/线/面的标记&#xff0c;标绘&#xff0c;显示等都是不可缺少的。本文主要是来介绍在地图上基于OpenLayers实现…

Qt-数据库开发-QTableView操作数据库(2)

Qt-数据库开发-QTableView操作数据库、自增Key 文章目录Qt-数据库开发-QTableView操作数据库、自增Key1、概述2、实现效果3、主要代码4、完整源代码更多精彩内容&#x1f449;个人内容分类汇总 &#x1f448;&#x1f449;数据库开发 &#x1f448; 1、概述 在开发数据库开发时…

40 | Linux安装node.js

1 环境准备 系统为ubuntu系统 2 下载压缩包 2.1 参考地址&#xff1a; https://nodejs.org/zh-cn/download/releases/2.2 创建文件夹 mkdir software wget https://nodejs.org/download/release/v16.18.0/node-v16.18.0-linux-x64.tar.gz2.3 解压 2.3.1 解压二进制文件…

docker——对镜像的操控笔记

一:镜像在哪里 这个问题问到点子上了,就好像说肉好吃,那你告诉我哪里才能买的到? 1. docker官方渠道 docker官方有一个 Docker Hub 网址,你能想到和想不到的镜像这上面都有,比如web开发者熟悉的nginx,redis,mongodb等等,而且还告诉 你怎么去下载,如下图: 接下来你可…

【Zookeeper】学习笔记(二)

Zookeeper学习笔记四、客户端命令4.1、新增节点4.2、查询节点信息4.3、节点类型4.4、更新节点4.5、删除节点4.6、监听器五、SpringBOOT整合Zookeeper六、写数据流程6.1、写流程之写入请求直接发送给Leader节点6.2、写流程之写入请求发送给follower节点七、服务器动态上下线监听…

Matlab 中 global 函数实例解析

目录 global 函数 案例分析 1 案例分析 2 使用golbal的优点 1. 传递大数据的参数 2. 过多的常量需要传递 global 函数 比如在主函数里面&#xff0c;你需要设置 Nc 这个变量是一个全局变量&#xff0c;就需要声明一下&#xff1a; global Nc; 然后在子函数里面你又用到了…

EMQX 多版本发布、新增自定义函数功能

11 月&#xff0c;EMQX 开源版和企业版分别发布了多个迭代版本&#xff0c;在安全性保障和生态集成方面又有了新的提升。 MQTT 消息云服务 EMQX Cloud 推出了新功能——自定义函数&#xff0c;用户可以更方便地将 IoT 数据处理为符合数据流的数据格式。 EMQX 11 月 EMQX 开源…

记一次golang struct字符串值被挤掉(被异常修改)的问题

使用的是gofiber框架&#xff0c;在包内设置了一个全局变量来保存数据&#xff0c;如下: var list make(map[int64]*Task, 10) type Task struct {ID int64Name string }gofiber设置了两个接口&#xff0c;一个是创建&#xff1a; func Create(c *fiber.Ctx) error {task : …

投票评选小程序毕业设计,微信投票小程序系统设计与实现,微信小程序毕业设计论文怎么写毕设源码开题报告需求分析怎么做

项目背景和意义 目的&#xff1a;本课题主要目标是设计并能够实现一个基于微信小程序评选投票系统&#xff0c;前台用户使用小程序&#xff0c;后台管理使用基PHPMySql的B/S架构&#xff1b;通过后台添加资讯、管理上传投票信息、用户管理等&#xff1b;用户通过小程序登录&…