【mini-react系列】一、createElement和render函数

前言

最近参加了 崔效瑞老师 的7天mini-react训练营,虽然每天工作很忙,但还是抽出一两个小时跟进学习,坚持了7天,还是得给坚持到最后的自己点个赞!

虽然之前没有接触过React的源码,但是通过学习任务的拆分,将复杂模块的任务拆分成一个个小任务,小步走实现,再逐步优化代码。

时间虽短,内容却不少。先开始浅浅地记录下我的学习成果,先起个好头,希望今年能顺利更新完这个系列,给2024的自己先立第一个flag!!

在这7天的mini-react训练营中,我学到了:

  • 实现createElementrender函数
  • 实现任务调度器requestIdleCallback
  • 实现简易的fiber
  • 实现functionComponent
  • 实现事件绑定
  • 实现props
  • 实现diff更新
  • 实现useState
  • 实现useEffect

话不多说,进入今天的主题,先开始React的初始化,实现createElementrender函数

createElement函数

createElement 函数是用于创建虚拟 DOM 元素的函数。它通常被 JSX 编译器所使用,用来将 JSX 语法转换为对 React.createElement 的调用。

js 复制代码
function createTextNode(text) {
  return {
    type: "TEXT_ELEMENT",
    props: {
      nodeValue: text,
      children: [],
    },
  }
}

function createElement(type, props, ...children) {
  return {
    type,
    props: {
      ...props,
      children: children.map((child) => {
        const isTextNode = typeof child === "string" || typeof child === "number"
        return isTextNode ? createTextNode(child) : child
      }),
    },
  }
}

createElement 函数接受三个参数:type 表示元素的类型(例如 'div'),props 表示元素的属性(例如 { className: 'my-class' }),以及 children 表示元素的子元素。在实现中,它返回一个包含 typeprops 属性的对象。

为了处理文本节点,我们还定义了 createTextNode 函数,它创建一个特殊的类型为 'TEXT_ELEMENT' 的对象,用于表示文本节点。

在实际使用中,React 会递归地处理这些虚拟 DOM 对象,最终将它们转换为实际的 DOM 元素并渲染到页面上。

复制代码
注意: 上述代码只是一个简化版的实现,真实的 React 源码中应该更加复杂,并包含更多的功能和优化。

render函数

render 函数是 React 中用于将虚拟 DOM 渲染到实际 DOM 的核心函数。

js 复制代码
function render(el, container) {
  const dom = el.type === "TEXT_ELEMENT"
    ? document.createTextNode("")
    : document.createElement(el.type)

  // id class
  Object.keys(el.props).forEach((key) => {
    if (key !== "children") {
      dom[key] = el.props[key]
    }
  })
  const children = el.props.children
  children.forEach((child) => {
    render(child, dom)
  })
  container.append(dom)
}

render 函数接受两个参数:element 表示要渲染的虚拟 DOM 元素,container 表示要渲染到的实际 DOM 容器。

首先,根据虚拟 DOM 的类型创建对应的实际 DOM 元素(文本节点和普通元素分别处理)。然后,将虚拟 DOM 元素的属性设置到实际 DOM 元素上,遍历子元素并递归调用 render 函数。最后,将创建好的实际 DOM 元素添加到容器中。

导出render函数

ReactDom文件导出render函数之后, 调用ReactDOM.createRoot(element).render 函数。这样,就可以使用 React 的渲染功能了。

js 复制代码
import React from "./React.js"
const ReactDOM = {
  createRoot(container) {
    return {
      render(App) {
        React.render(App, container)
      },
    }
  },
}

export default ReactDOM

示例解析

简单的渲染代码

jsx 复制代码
function App() {
  return (
    <div>
      hello world, my mini react!
      <div>befend</div>
    </div>
  )
}

export default App;

节点创建的过程内容

渲染结果

小结

  • createElementrender 是 React 中用于构建和渲染界面的核心函数。
  • 通常,createElement 函数用于创建虚拟 DOM 元素,通常由 JSX 编译器转换 JSX 语法时调用。而 render 函数将虚拟 DOM 渲染到实际 DOM。

总的来说,createElement 用于创建虚拟 DOM 元素,而 render 用于将这些虚拟 DOM 元素渲染到实际 DOM 中,从而构建用户界面。

仓库传送门: github.com/Befend/mini...

相关推荐
伍哥的传说6 小时前
React 各颜色转换方法、颜色值换算工具HEX、RGB/RGBA、HSL/HSLA、HSV、CMYK
深度学习·神经网络·react.js
浪裡遊7 小时前
React Hooks全面解析:从基础到高级的实用指南
开发语言·前端·javascript·react.js·node.js·ecmascript·php
前端小盆友12 小时前
从零实现一个GPT 【React + Express】--- 【3】解析markdown,处理模型记忆
gpt·react.js
Cacciatore->13 小时前
React 基本介绍与项目创建
前端·react.js·arcgis
摸鱼仙人~13 小时前
React Ref 指南:原理、实现与实践
前端·javascript·react.js
贵沫末14 小时前
React——基础
前端·react.js·前端框架
爱学习的茄子14 小时前
AI驱动的单词学习应用:从图片识别到语音合成的完整实现
前端·深度学习·react.js
10年前端老司机15 小时前
在React项目中如何封装一个可扩展,复用性强的组件
前端·javascript·react.js
sophie旭15 小时前
《深入浅出react开发指南》总结之 10.1 React运行时总览
前端·react.js·源码阅读
轻语呢喃15 小时前
React智能前端:从零开始写的图片分析页面实战
前端·react.js·aigc