仿写一个自己的react(第一章)

本文介绍了如何从零开始实现一个简化版的React框架——mini_react。通过解析React的渲染流程,逐步指导读者理解并实践从JSX到DOM的转换过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

仿写一个我们自己的mini_react(第一章)


前言

我觉得大家也有过一种大胆的想法想写一个前端框架吧,这些本来应该是是我在梦里边的行为,但是看了一个大哥推荐的一篇文章后,我觉得我也可以,所以我们一起试着写一个吧

大哥的csdn地址:https://lpyexplore.blog.youkuaiyun.com/

文章的地址:https://pomb.us/build-your-own-react/

1.首先我们先了解一下react的渲染过程

其实jsx是通过一种打包方式打包成真正的js代码

const element = <h1 title="foo">Hello</h1>
const container = document.getElementById("root")
ReactDOM.render(element, container)
  • 首先有一个组件,要有一个根节点root,通过render函数将组件渲染到根节点上

2.是通过什么方式将上文中的element组件转化为一个js文件呢?

举一个例子:

import React from 'react'
function App () {
    return (
        <div>
        	你吃饭了嘛
        </div>
    )
}

这个就是我们常常写的react的代码,现在有一个问题:我们没有用到react的方法为什么还要引用呢?

答:虽然表面上没有用但是在jsx打包时候会运行 React.createElement方法将html元素转化为一个对象

例子:

const element = <h1 title="foo">Hello</h1>
      
const element = React.createElement(
  "h1",
  { title: "foo" },
  "Hello"
)

现在我们知道了一个元素会变成这样的对象额。。。那就好办了我们来写一个实现他的简单方法

3.将对象那形式的元素变成真正的dom元素

<body>
    <div id="root"></div>

    <script>
        // 第一步 获取根节点
        let container = document.querySelector('#root')

        // 第二步手动创建虚拟的元素对象
        const element = {
            type: "h1",
            props: {
                title: "foo",
                children: "Hello"
            }
        }

        // 第三步由虚拟的元素对象创建一个元素
        const node = document.createElement(element.type)
        node['title'] = element.props.title

        const text = document.createTextNode('')
        text['nodeValue'] = element.props.children
        

        node.appendChild(text)
        container.appendChild(node)
    </script>
    
</body>

运行结果:

在这里插入图片描述

写到这其实我就挺激动了,一直不管学vue还是react都是应用层面,这些js的底层代码写着还真有意思

试着实现React.createElement方法

前言:我想想仿写一个方法,首先要知道他实现了什么功能

功能需求:我就想以传递函数参数的形式让createElement方法帮我创建一个虚拟元素对象

 // 第一步 获取根节点
let container = document.querySelector('#root')

// 实现方法:React.createELement
// type: 元素的标签,props:元素的标签,...children:子元素
function createELement (type, props, ...children) {
    return {
        type,
        props: {
            ...props,
            children
        }
    }
}

这样我们就实现了通过函数传参数就可以形成虚拟的元素对象

但是现在又有一个问题:如果我的子元素他仅仅是一个文本我想更好的管理他应该怎么做?

答:对上述代码进行优化

// 第一步 获取根节点
let container = document.querySelector('#root')

// 实现方法:React.createELement
// 判断传进的children参数是否为一个元素
function createELement (type, props, ...children) {
    return {
        type,
        props: {
            ...props,
            children: children.map(child => {
                return typeof child === 'object'
                    ? child
                : createELement(child)
            })
        }
    }
}

// 给纯文本的子节点创建一个type: 'TEXT_ELEMENT'方便管理
function createTextElement (text) {
    return {
        type: 'TEXT_ELEMENT',
        props: {
            nodeText: text,
            children: []
        }
    }
}

现在舒服的一批,同时呢又显得高级

提示!:

// 为了像react那样统一管理方法我们船舰一个对象来管理我们mini_react...帅就完了
const mini_react = {
    createELement
}
好了第一章就到这里吧,下一章我们实现render方法
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值