Skip to content

Rchard-Lee/mini-react

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

mini-react

在页面中呈现出文字(开始重构React api)

-(1)vdom写死,dom渲染写死

-(2)vdom动态生成,dom渲染写死

-(3)vdom动态生成,dom动态递归生产

ps:jsx语法本质是通过借助babel、vite、webpack等工具,转换成React.createElement函数,该函数返回vdom

ps1: 如果不想被转换成React.createElement,可以在页面顶部通过注释(这种注释叫做:js pragma): /**@jsx LReact.create(自定义名) */ 即可。(vite中如此,其他工具有待考证)

实现任务调度器

为什么要实现任务调度器?

- dom树特别大,导致页面渲染卡顿

解决思路

- 把大任务拆分到多个task里面完成

实现

- 采用requestIdleCallback分帧运算

requestIdleCallback(calc)在浏览器有空余时间时会调用回调函数,但是如果回调函数calc一直执行,浏览器依然会卡住,这时候就需要采用注入calc(deadline)中deadline.timeRemaining()拿到剩余空闲时间决定当前回调是否继续执行。

实现fiber架构

问题:如何做到每次只渲染几个节点?下次执行时依然从之前的位置执行?

解决思路:把树结构转变成链表结构:

- child

- sibling

- parent

实现performUnitOfWork

1. 创建dom

2. 把dom添加到父级容器内

3. 设置dom的props

4. 建立关系child sibling parent

5. 返回下一个节点

目标:统一提交

问题:中途有可能没有空余时间,用户会看到渲染到一半的dom

解决思路:计算结束后统一添加到屏幕里面。

==========================================================================================

实现支持Function Component

解决思路: 把FC当作一个盒子,返回值为需要拆解的内容

实现:

1. type的处理(判断是不是FC)

2. 根据type区别FC和非FC

3. 添加到视图的处理(FC不需要挂载真实DOM,其孩子节点需要通过递归等挂载到其FC的父DOM上)

实现绑定事件

解决思路:基于onClick来注册点击事件

实现更新props

解决思路:对比新 vdom树和旧 dom树。

问题:

- 如何得到新的dom树? 通过去拿最外层的容器,按照最初生成dom树的方式(render),生成新的dom树(update)

# - 如何找到老的节点? 通过在构建新dom树的时候,用属性alternate将新旧节点关联起来

- 如何diff props? 通过属性alternate将新节点与老节点绑定

diff-更新中的创建和删除

当更新时遇到类型不一致时,需要删除旧的创建新的

当更新时新的节点比老的节点短,需要删除多余的节点

更新子组件的时候,其他不相关的组件不重新执行,避免浪费

1. 之前:从根节点出发 =》 从当前更新的组件节点出发 利用闭包记录每个函数组件的fiber,之后调用update的时候可以找到对应组件
2. 之前:遍历完整棵树作为结束 =》 处理兄弟节点的时候作为结束 在任务调度的时候判断当前渲染组件的兄弟节点是不是下一个渲染节点,是的话不再继续而是开始渲染

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published