框架原理
如何组织UI与逻辑
组件内部工作流程
架构
Schedule阶段
lane模型在React中的应用
状态更新流程
事件系统
- 合成事件
- 事件传播机制
对合成事件的理解
- react组件中编写的事件是绑定在dom上么,如果不是绑定在哪里? 绑定在fiber节点的属性中;在react首次挂载时,给根元素绑定了用于接受委托的函数,当事件发生时,所有事件都委托给根元素处理;处理的过程中,react会找到事件发生的dom对应的fiber,并通过收集其到根节点的路径上的节点相应的事件回调函数,最终来模拟捕获、冒泡的实现
- 为什么不能用 return false 来阻止事件的默认行为?
- react怎么通过dom元素,找到与之对应的 fiber对象的?dom对象上设置了能找到对应fiber的属性
ReactDOM.createRoot流程
useState流程
使用useState触发更新时,会调用源码的dispatchSetState方法
其中,会使用isRenderPhaseUpdate(fiber)判断是否是render阶段触发的更新
个人理解:如果是在render阶段,是否开启新的调度取决于调度器的分配;在其他阶段,则可以直接开启新的调度
性能优化
eagerState策略
如果某个状态更新前后没有变化,则可以跳过后续更新流程
时机:在更新发生时,schedule流程之前进行;
判断:当前fiberNode不存在‘待执行的更新’;此时触发的这个更新产生的更新是当前fiberNode中第一个带执行的更新,计算state不受其他update影响
命中条件:更新前后状态没有变化
结果:这个更新跳过后续的流程,不会更新fiebrNode.lanes
bailout策略
父组件命中bailout,则复用子fiber, 也就是说父组件bailout决定是否复用子fiber
React fiber中自变量包括state、props、context,第一次bailout对这三种变量有没有变化进行判断,命中则表示当前fiber没有变化
疑问
- 第二次判断bailout中,如果有更新但state无变化,则表示命中bailout,那是否意味这与props和context是否变化无关?
对日常开发的启示
追求写出满足bailout策略的组件
- 默认情况下(没有性能优化api以及不是有更新但无状态变化的情况),fiberNode要命中bailout策略需要满足oldProps===newProps,这意味着在默认情况下,如果父fiber没有命中策略,子fiberNode就不会命中策略,后代的fiberNode都不会命中策略
- 值得注意的是,对于第一次没有命中bailout的情况,在第二次判断是否命中bailout前,会先执行组件的渲染。也就是说,对于在执行render时有耗时任务的组件,只要没有命中bailout,就不可避免的要进行render以及其中的耗时任务的执行。因此,在开发中,应该尽量对有耗时任务的组件进行分离,并且最好将其放在常常会命中bailout的父组件中