当前位置: 首页 > Web前端 > HTML

自己创建一个ReactDOM

时间:2023-03-28 17:57:41 HTML

大家好,我是Kason。React可以看做是三部分的组合:scheduler,scheduler,用于调度任务reconciler,coordinator,用于计算任务引起的副作用renderer,renderer,用于在宿主环境中执行副作用,这三个是独立的封装,我们项目中引入的ReactDOM可以看做是将以下三部分代码进行了封装:scheduler的主要逻辑,reconciler的逻辑,ReactDOMrenderer的主要逻辑。本文将教你如何基于官方的reconciler实现一个迷你的ReactDOM。本文参考HelloWorldCustomReactRenderer项目初始化通过CRA构建项目(或使用现有项目):create-react-appxxx新建customRenderer.js,引入react-reconciler并完成初始化://Thereconciler本文使用的版本是0.26。2从'react-reconciler'导入ReactReconciler;consthostConfig={};constReactReconcilerInst=ReactReconciler(hostConfig);其中hostConfig为宿主环境的配置项。最后,customRenderer.js导出一个包含渲染方法的对象:dom元素,假);}返回ReactReconcilerInst.updateContainer(reactElement,domElement._rootContainer,null,callback);}};在项目入口文件中,将ReactDOM替换为我们实现的CustomRenderer:importReactDOMfrom'react-dom';importCustomRendererfrom'./customRenderer';//替换ReactDOMCustomRenderer.render(,document.getElementById('root'));实现ReactDOM接下来,我们实现hostConfig配置,先填空函数,避免应用报错:,shouldSetTextContent(){},createInstance(){},createTextInstance(){},appendInitialChild(){},finalizeInitialChildren(){},clearContainer(){},appendInitialChild(){},appendChild(){},appendChildToContainer(){},prepareUpdate(){},commitUpdate(){},commitTextUpdate(){},removeChild(){}}注意这里唯一的布尔配置项supportsMutation表示宿主环境的API支持突变。是DOMAPI的工作方式,例如element.appendChild、element.removeChild。如果是Native环境,这不是工作方式。接下来我们实现这些API。实现API这些API可以分为以下几类。初始化环境信息getRootHostContext和getChildHostContext用于初始化上下文信息。生成DOM节点createInstance用于创建DOM节点createTextInstance用于创建文本节点CreateTextInstance可以实现如下:createTextInstance:(text)=>{returndocument.createTextNode(text);}关键逻辑判断shouldSetTextContent用于判断组件的子节点是否为文本节点,实现如下:shouldSetTextContent:(_,props)=>{returntypeofprops.children==='string'||typeofprops.children==='number';},DOM操作appendInitialChild用于插入DOMNode,实现如下:appendInitialChild:(parent,child)=>{parent.appendChild(child);},commitTextUpdate用于更改文本节点,实现如下:commitTextUpdate(textInstance,oldText,newText){textInstance.text=newText;},removeChild用于删除子节点,实现如下:removeChild(parentInstance,child){parentInstance.removeChild(child);}当所有API都实现后,页面就可以正常渲染了:完整的demo地址见:完整的Demo地址总结学习了这篇文章,我们实现了一个简单的ReactDOM。如果你想在任何可以绘制UI的环境中使用React,你可以使用react-reconciler在这个环境中实现React。例如,IntroductionToReactNativeRenderers教你如何在Native环境中实现React。欢迎加入人类优质前端框架群,独占鳌头