资讯专栏INFORMATION COLUMN

React 的最小实现 - Kut

mist14 / 2843人阅读

摘要:是基于的最小实现。的实现可以参考这篇文章,我称其为前向。而为简单起见,仍使用原生事件,采用事件委托的方式,将所有监听函数挂在上。的做法参考了的做法,实现了在上添加和删除监听函数的方法,并以判断触发的节点。

Kut


Kut,一个简单的React-Like的前端视图渲染库,是我在学习React源码时造的轮子。Kut是基于Typescript的React最小实现。目前Kut支持的Top-Level方法仅有两个,即createElement、render,同时也支持组件化开发,Demo在这里。

本文主要对Kut的源码进行说明和记录,项目地址:Github。

源码说明

源码都在src目录下,目前一共9个文件,分别如下。

component.ts

定义了Component类,以用于自定义组件,只是定义了一些属性和方法,与React的Component类似。

element.ts

Element是用于构造Virtual DOM节点的对象,element.ts中包含一个工厂函数createElement。Element有3个属性:type是类型,可以是DOM tag(如div等)或自定义组件(即Component子类);key用于diff时对节点进行唯一区分;children是子节点数组,其元素可以是文本或者Element,和React的区别是,如果children只有一项时,Kut的children仍是数组,不过只有一项。

instance.ts

instance.ts中包含了三种不同类型Element对应的实例类Instance,对应ReactComponent(注意区别Component,为避免混淆,Kut中命名为Instance),分别为文本实例TextInstance、DOM节点实例DOMInstance和自定义组件实例ComponentInstance。三种Instance类结构基本类似,首先包含其对应于DOM节点的唯一kutId,以方便进行挂载、更新和卸载;而index只用于列表项没指定key时使用,可忽略;key和node用于获取DOM节点的key和节点本身。

Instance的价值主要在于mount、shouldReceive、update和unmount方法。mount方法用于遍历VDOM树,拼接HTML和添加监听函数。而shouldReceive用于判断是否为同一节点,若Element的type和key相同,则直接调用update更新,否则调用unmount卸载并重新mount挂载。update方法则递归更新以当前节点为根节点的VDOM子树,其中若children大于一项的,会使用diff算法计算其差异并调用patch进行更新。最后,unmount方法则从DOM树上卸载节点,并清除引用。

diff.ts

对于列表项更新,需要使用diff算法计算其差异。React的实现可以参考这篇文章,我称其为前向diff。Kut基本的实现逻辑和React是相似的,但对于把元素从列表中底部挪到顶部的做法,React的前向diff会导致DOM更新操作过多。Kut的做法是引入后向diff,逻辑是和前向diff一致,只是方向相反,时间复杂度仍为O(n)。取前向diff和后向diff的更新操作较少者,调用patch函数对DOM进行更新。这部分解释我都写在了diff.ts的注释里了。

kut.ts/renderer.ts/constant.ts/util.ts

分别是入口文件、渲染方法、一些常量和一些工具函数。其中renderer.ts中定义了Element实例化instantiate函数(即由Element生成Instance)和render函数(使用innerHTML进行挂载),由于采用innerHTML方法进行挂载,需要使用事件委托来处理事件,也需要使用DOM节点唯一kutId进行区别,具体见event.ts。

event.ts

React为保证兼容性,具有合成事件。而Kut为简单起见,仍使用原生事件,采用事件委托的方式,将所有监听函数挂在document上。event.ts的做法参考了的做法,实现了在document上添加和删除监听函数的方法,并以kutId判断触发的节点。

后续计划

最近忙着实习面试和论文暂时也没太多时间加新功能,现在仍然有些bug,如componentDidMount的触发时机不对。慢慢先打算支持异步更新和Context,起码让Redux能用对吧,先写篇记录免得后头来看连自己都忘了(苦笑)。推荐个最近看到的关于React源码的专栏,感觉讲得还不错的,在这里:编程小思。

欢迎pr和stars,项目地址:Github。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/93827.html

相关文章

  • 前端面试题大集合:来自真实大厂532道面试题(只有题,没有答案)

    答案自己谷歌或百度找。 一、来源背景 面试题是来自微博@牛客网发布的真实大厂前端面经题目,我一直在收集题目长期一个一个的记录下来的,可能会有重复,但基本前端的面试大纲和需要掌握的知识都在其中了,面试题仅做学习参考,学习者阅后也要用心钻研其中的原理,重要知识需要系统学习、透彻学习,形成自己的知识链。 二、532道前端真实大厂面试题 express和koa的对比,两者中间件的原理,koa捕获异常多种情...

    Kerr1Gan 评论0 收藏0
  • 前端面试题大集合:来自真实大厂532道面试题(只有题,没有答案)

    答案自己谷歌或百度找。 一、来源背景 面试题是来自微博@牛客网发布的真实大厂前端面经题目,我一直在收集题目长期一个一个的记录下来的,可能会有重复,但基本前端的面试大纲和需要掌握的知识都在其中了,面试题仅做学习参考,学习者阅后也要用心钻研其中的原理,重要知识需要系统学习、透彻学习,形成自己的知识链。 二、532道前端真实大厂面试题 express和koa的对比,两者中间件的原理,koa捕获异常多种情...

    lushan 评论0 收藏0
  • 前端面试题大集合:来自真实大厂532道面试题(只有题,没有答案)

    答案自己谷歌或百度找。 一、来源背景 面试题是来自微博@牛客网发布的真实大厂前端面经题目,我一直在收集题目长期一个一个的记录下来的,可能会有重复,但基本前端的面试大纲和需要掌握的知识都在其中了,面试题仅做学习参考,学习者阅后也要用心钻研其中的原理,重要知识需要系统学习、透彻学习,形成自己的知识链。 二、532道前端真实大厂面试题 express和koa的对比,两者中间件的原理,koa捕获异常多种情...

    joyvw 评论0 收藏0
  • 11 个最好 JavaScript 动态效果库

    摘要:经过一番研究,我收集了个最好的库,你可以用在自己的项目中。该库于年月首次推出,目前仍有近名参与者开发。超过的,是一个动画库,可以处理属性单个转换或任何属性,以及对象。对智能设备的方向作出反应的视差引擎快速创建漂亮的动画。 翻译:疯狂的技术宅原文:https://blog.bitsrc.io/11-jav... 当我想要在网上找一个简洁的 Javascript 动效库时,总是发现很多推...

    wawor4827 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<