setState 和 forceUpdate
1 ) 概述
- 通过 class component 内部的
setState
,以及forceUpdate
去更新一个组件的过程 - 在react的应用当中,我们只有
ReactDOM.render
setState
,以及forceUpdate
- 这几种种方式去更新react的应用是合理的,其他没有什么特别常用的方式去更新了
- 而且react官方推荐的也是用这些。
forceUpdate
其实本身也不是特别推荐的 - 因为有比较特殊的作用,以及比较特殊的使用场合, 也算是一个比较有用的API
- 在React16.7之后发布的Hooks, Hooks里面我们通过
-
useState
返回过来的一个方法,也可以去更新一个组件的状态- 这块看不到源码,只能看到打包之后的代码
- 它的设置比较特殊,这块先跳过
-
setState
,以及forceUpdate
的核心,首先是他们是给节点Fiber
去创建更新的 - 对于
ReactDOM.render
来说,它创建的 update 是放在root上面 - 它是一个整体的渲染,因为执行
ReactDOM.render
的时候 - 整个应用都没有任何的产生,任何的节点都没有生成,是一个初始的渲染
- 所以
setState
和forceUpdate
是针对某一个 class component 来说的- 这个 class component 的状态来进行更新
- 把新的状态计算并渲染出来
-
setState
和forceUpdate
两者更新的类型不同- 它们上面有
UpdateState
,ForceUpdate
两种不同的 tag - 这个tag就对应的它们是更新的类型不同
- 它们上面有
2 )源码
-
先跳过 组件如何去渲染
- 也就是我们的 class component,什么时候会被实例化
- 这个涉及到后面的更新的流程
-
我们的component的BaseClass在初始化的时候会拿到一个update的这个对象
-
这个对象来自于哪个地方
-
源码: https://github.com/facebook/react/blob/v16.6.0/packages/react-reconciler/src/ReactFiberClassComponent.js
-
这个文件中,有涉及很多 class 相关的代码
const classComponentUpdater = { isMounted, enqueueSetState(inst, payload, callback) { const fiber = ReactInstanceMap.get(inst); // inst 是调用 this.setState 时的 this,在react渲染的时候会通过 `ReactInstanceMap` 做映射和获取 Fiber对象 const currentTime = requestCurrentTime(); const expirationTime = computeExpirationForFiber(currentTime, fiber); const update = createUpdate(expirationTime); update.payload = payload; // 这里 payload 是 setState时传入的对象 if (callback !== undefined && callback !== null) { if (__DEV__) { warnOnInvalidCallback(callback, 'setState'); } update.callback = callback; // 挂载 callback } enqueueUpdate(fiber, update); // 把fiber对象的updateQueue进行初始化或更新 scheduleWork(fiber, expirationTime); // 进行调度处理 }, enqueueReplaceState(inst, payload, callback) { const fiber = ReactInstanceMap.get(inst); const currentTime = requestCurrentTime(); const expirationTime = computeExpirationForFiber(currentTime, fiber); const update = createUpdate(expirationTime); update.tag = ReplaceState; update.payload = payload; if (callback !== undefined && callback !== null) { if (__DEV__) { warnOnInvalidCallback(callback, 'replaceState'); } update.callback = callback; } enqueueUpdate(fiber, update); scheduleWork(fiber, expirationTime); }, enqueueForceUpdate(inst, callback) { const fiber = ReactInstanceMap.get(inst); const currentTime = requestCurrentTime(); const expirationTime = computeExpirationForFiber(currentTime, fiber); const update = createUpdate(expirationTime); update.tag = ForceUpdate; if (callback !== undefined && callback !== null) { if (__DEV__) { warnOnInvalidCallback(callback, 'forceUpdate'); } update.callback = callback; } enqueueUpdate(fiber, update); scheduleWork(fiber, expirationTime); }, };
- 这里面主要关注,
enqueueSetState
和enqueueForceUpdate
这两个enqueue 方法几乎一样,两者区别 看update.tag
- 看了上面的源码,发现 和 react-reconciler/src/ReactFiberReconciler.js 中的
updateContainer
很像- 内部调用
updateContainerAtExpirationTime
接着调用scheduleRootUpdate
在这里面都基本相似
- 内部调用
- 这里面主要关注,
-
所以,在React中创建更新的过程都是差不多的,创建完更新后,进入队列,就会进行整个应用的更新
-
React 是一个非常纯粹的框架,所有的核心都是服务应用的整体更新的, 就是
scheduleWork
函数进入之后的整体更新流程文章来源:https://www.toymoban.com/news/detail-824298.html -
这块在React整体的代码量中占据非常大的比例文章来源地址https://www.toymoban.com/news/detail-824298.html
到了这里,关于React16源码: React中的setState和forceUpdate源码实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!