1 ) 概述
setState
,以及 forceUpdate
去更新一个组件的过程ReactDOM.render
setState
,以及 forceUpdate
forceUpdate
其实本身也不是特别推荐的useState
返回过来的一个方法,也可以去更新一个组件的状态
setState
,以及 forceUpdate
的核心,首先是他们是给节点 Fiber
去创建更新的ReactDOM.render
来说,它创建的 update 是放在root上面ReactDOM.render
的时候setState
和 forceUpdate
是针对某一个 class component 来说的
setState
和 forceUpdate
两者更新的类型不同
UpdateState
, ForceUpdate
两种不同的 tag2 )源码
先跳过 组件如何去渲染
我们的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
updateContainer
很像
updateContainerAtExpirationTime
接着调用 scheduleRootUpdate
在这里面都基本相似所以,在React中创建更新的过程都是差不多的,创建完更新后,进入队列,就会进行整个应用的更新
React 是一个非常纯粹的框架,所有的核心都是服务应用的整体更新的, 就是 scheduleWork
函数进入之后的整体更新流程
这块在React整体的代码量中占据非常大的比例