自己造一个ReactDOM

域名2025-11-05 06:27:2274

大家好,自己造我卡颂。自己造

React可以看作是自己造三部分的组合:

scheduler,调度器,自己造用于调度任务 reconciler,自己造协调器,自己造用于计算任务造成的自己造副作用 renderer,渲染器,自己造用于在宿主环境执行副作用

这三者都是自己造独立的包,我们项目里引入的自己造ReactDOM可以看作是以下三部分代码打包而成:

scheduler的主要逻辑 reconciler部分逻辑 ReactDOM renderer的主要逻辑

本文会教你如何基于官方的reconciler,实现迷你ReactDOM。自己造

本文参考Hello World Custom React Renderer[1]

项目初始化

通过CRA建立项目(或用已有项目):

create-react-app xxx 

新建customRenderer.js,自己造引入react-reconciler并完成初始化:

// 本文使用的企商汇自己造reconciler版本是0.26.2 import ReactReconciler from react-reconciler; const hostConfig = {}; const ReactReconcilerInst = ReactReconciler(hostConfig); 

其中hostConfig就是宿主环境的配置项。

最后,自己造customRenderer.js导出一个包含render方法的自己造对象:

export default {   render: (reactElement, domElement, callback) => {     // 创建根节点     if (!domElement._rootContainer) {       domElement._rootContainer = ReactReconcilerInst.createContainer(domElement, false);     }     return ReactReconcilerInst.updateContainer(reactElement, domElement._rootContainer, null, callback);   } }; 

在项目入口文件,将ReactDOM换成我们实现的CustomRenderer:

import ReactDOM from react-dom; import CustomRenderer from ./customRenderer; // 替换ReactDOM CustomRenderer.render(   <App />,   document.getElementById(root) ); 

实现ReactDOM接下来我们实现hostConfig配置,首先填充空函数避免应用报错:

const hostConfig = {   supportsMutation: true,   getRootHostContext() {},   getChildHostContext() {},   prepareForCommit() {},   resetAfterCommit() {},   shouldSetTextContent() {},   createInstance() {},   createTextInstance() {},   appendInitialChild() {},   finalizeInitialChildren() {},   clearContainer() {},   appendInitialChild() {},   appendChild() {},   appendChildToContainer() {},   prepareUpdate() {},   commitUpdate() {},   commitTextUpdate() {},   removeChild() {} } 

注意这里唯一一个Boolean类型的配置项supportsMutation,他表示宿主环境的API支持mutation。

这是DOM API的工作方式,比如element.appendChild、element.removeChild。如果是Native环境则不是这种工作方式。

接下来我们来实现这些API。香港云服务器

实现API

这些API可以分为如下几类。

初始化环境信息

getRootHostContext与getChildHostContext用于初始化上下文信息。

生成DOM节点

createInstance用于创建DOM节点 createTextInstance用于创建文本节点

可以将createTextInstance实现如下:

createTextInstance: (text) => {   return document.createTextNode(text); } 

关键逻辑的判断

shouldSetTextContent用于判断组件的children是否是文本节点,实现如下:

shouldSetTextContent: (_, props) => {     return typeof props.children === string || typeof props.children === number; }, 

DOM操作

appendInitialChild用于插入DOM节点,实现如下:

appendInitialChild: (parent, child) => {   parent.appendChild(child); }, 

commitTextUpdate用于改变文本节点,实现如下:

commitTextUpdate(textInstance, oldText, newText) {   textInstance.text = newText; }, 

removeChild用于删除子节点,实现如下:

removeChild(parentInstance, child) {   parentInstance.removeChild(child); } 

当实现了所有API后,页面就能正常渲染了:

完整实现的Demo地址见:完整Demo地址[2]

总结

经过本文的学习,我们实现了一个简易ReactDOM。

如果你想在任何可以绘制UI的环境使用React,都可以利用react-reconciler实现该环境下的React。

比如,Introduction To React Native Renderers[3]教你如何在Native环境实现React。

参考资料

[1]Hello World Custom React Renderer:

https://agent-hunt.medium.com/hello-world-custom-react-renderer-9a95b7cd04bc

[2]完整Demo地址:

https://codesandbox.io/s/quiet-feather-05gvk?file=/src/index.js

[3]Introduction To React Native Renderers:

https://agent-hunt.medium.com/introduction-to-react-native-renderers-aka-react-native-is-the-java-and-react-native-renderers-are-828a0022f433

网站模板
本文地址:http://www.bzuk.cn/html/104b30799588.html
版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。

全站热门

解决电脑上网弹出证书错误的方法(探索证书错误的原因及应对之道)

Java中常用的缓存框架

互联网寒冬下,Go语言平均薪资高达29K,为什么?

面向对象之三个基本特征(JavaScript)

给计算机装双系统的完全教程(轻松搭建双系统,满足不同需求)

用Python偷偷告诉你国庆8亿人都去哪儿浪?

咱们从头到尾说一次Java的垃圾回收

谁说 Vim 不好用?送你一个五彩斑斓的编辑器!

友情链接

滇ICP备2023006006号-33