1、目的
PS: 这句话必须要写,读了一些源码我发现,他们也只是普通的代码,不过他们考虑到性能/扩展/维护/可读/间接/优秀的逻辑和设计模式,我们应学习这些,当然也不要怕他们是洪水猛兽
- 之前好像写给如何读源码的,不过那次是简单方法论,这次我们不仅重新总结一下方法,并且
实践一下,简单读一读 React
2、方法论
1.问题驱动, 比如 React setState如何起作用的,更新过程是怎样的,React fiber 到底神奇在哪里?如何提升性能的? 2.最新的源码,不仅是思维升级,还是可读性升级,学习成本 🆙 🆙 3.结构,项目有哪些组成部分,为了达到最终的产出,要经过哪几步流程。这些流程里,业界主流的方案有哪几种 4.本地 g clone xxx 拿下来 并且跑起来 ,为了更好的跑起来,找到类似这样的文件 **Contribution Guide** 这个文件会告诉你哪里可以进行预览你的更改 5.在自己想了解的地方 打## debugger && log 然后 想办法 打出自己的 log 6.关注官网动态和核心开发者动态 复制代码
网络异常,图片无法展示
|
- 结构更多解释来源于 蚂蚁团队 请放心参考
比如前端 View 层框架,要渲染出 UI,组件要经过 mount、 render 等等步骤。数据驱动的前端框架, 在 mounted 之后,就会进入一个循环,当用户交互触发组件数据变化时,会更新 UI。其中数据的检测方式 又有分 Push 和 Pull 两种方案。渲染 UI 可以是全量的字符串模板替换,也可以是基于 Virtual DOM 的 差量 DOM 更新。 又比如前端的一些工具,Webpack 和 Babel 这些工具都是基于插件的。基本的工作流程就是读取文件, 解析代码成 AST,调用插件去转换 AST,最后生成代码。要了解 Webpack 的原理,就要知道 Webpack 基于 一个叫 [tapable](https://link.zhihu.com/?target=https%3A//github.com/webpack/tapable) 的模块系统 复制代码
- 项目结构 更多 解释
需要找到 package / src / bin / lib 下的 核心文件部分
- 比如React
网络异常,图片无法展示
|
网络异常,图片无法展示
|
网络异常,图片无法展示
|
3、实践 以 React setState 为例 看看发生了什么
- 前提
- React Core 包含了 React 的类定义和一些顶级 API。大部分的渲染和 View 层 diff 的逻辑都在 Reconciler 和 Renderer 中
步骤总结
1、 找到setState 相关内容
2、setState的入口文件在src/isomorphic/modern/class/ReactBaseClasses.js
- 此处 挂在 原型链上
Component.prototype.setState = function(partialState, callback) { if ( typeof partialState !== 'object' && typeof partialState !== 'function' && partialState != null ) { throw new Error( 'setState(...): takes an object of state variables to update or a ' + 'function which returns an object of state variables.', ); } debugger this.updater.enqueueSetState(this, partialState, callback, 'setState'); }; 复制代码
- 在看这个
入口方法
enqueueSetState 定义 在此处 ReactNoopUpdateQueue.js
function enqueueUpdate(component) { ensureInjected(); if (!batchingStrategy.isBatchingUpdates) { batchingStrategy.batchedUpdates(enqueueUpdate, component); return; } dirtyComponents.push(component); if (component._updateBatchNumber == null) { component._updateBatchNumber = updateBatchNumber + 1; } } 复制代码
if (!batchingStrategy.isBatchingUpdates) { batchingStrategy.batchedUpdates(enqueueUpdate, component); return; } dirtyComponents.push(component); 复制代码
判断batchingStrategy.isBatchingUpdates batchingStrategy是批量更新策略,isBatchingUpdates表示是否处于批量更新过程,开始默认值为false
网络异常,图片无法展示
|
3、事务流 batchedUpdates => 调用transaction
var ReactDefaultBatchingStrategy = { isBatchingUpdates: false, batchedUpdates: function(callback, a, b, c, d, e) { var alreadyBatchingUpdates = ReactDefaultBatchingStrategy.isBatchingUpdates; ReactDefaultBatchingStrategy.isBatchingUpdates = true; if (alreadyBatchingUpdates) { return callback(a, b, c, d, e); } else { return transaction.perform(callback, null, a, b, c, d, e); } }, }; module.exports = ReactDefaultBatchingStrategy; 复制代码
当isBatchingUpdates为true,处于更新事务状态中,则将Component存入dirtyComponent中, 否则调用batchedUpdates处理,发起一个transaction.perform()
4、 batchingStrategy 批量更新策略
var ReactDefaultBatchingStrategy = { isBatchingUpdates: false, batchedUpdates: function(callback, a, b, c, d, e) { var alreadyBatchingUpdates = ReactDefaultBatchingStrategy.isBatchingUpdates; ReactDefaultBatchingStrategy.isBatchingUpdates = true; if (alreadyBatchingUpdates) { return callback(a, b, c, d, e); } else { return transaction.perform(callback, null, a, b, c, d, e); } }, }; 复制代码
- 非常明显isBatchingUpdates的初始值是false的,在调用batchedUpdates方法的时候会将isBatchingUpdates变量设置为true
4、小结
- 这是一个 小的切入点,但有了方法和例子,之后的阅读源码将通畅很多,大伙儿 可以赶快试试,有问题可以和我沟通,感谢支持,感谢👍
Last 参考文档
1.蚂蚁技术团队
作者:马克付
链接:https://juejin.cn/post/7142397447095091213
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。