北师大网页制作与网站建设期末考试,seo1搬到哪里去了,长安镇做网站,如何让网站排名下降setState 和 forceUpdate
1 #xff09; 概述
通过 class component 内部的 setState#xff0c;以及 forceUpdate 去更新一个组件的过程在react的应用当中#xff0c;我们只有 ReactDOM.render setState#xff0c;以及 forceUpdate这几种种方式去更新react的应用是合理…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 函数进入之后的整体更新流程 这块在React整体的代码量中占据非常大的比例