this.setState(paticalState,callback)过程
会调用 this.updater.enquenSetState(this,paticalState,callback,’setState’),
enquenSetState 内部调用了 ReactInstanceMap.get(component也就是this)获取到了fiber实例,然后基于performance.now()||Date.now()获取到currentTime,用createUpdate(currentTime)创建了update对象(单链表节点格式对象,最终调用 enquenUpdate(fiber,update)来update。
enquenUpdate源码
//以下注释仅对 ClassComponent有效(即你的组件是继承React.Component)
export function enqueueUpdate<State>(fiber: Fiber, update: Update<State>) {
// Update queues are created lazily. Update queues被延迟创建(即这个组件没有update 我们没有必要给它fiber来创建这样属性)
const alternate = fiber.alternate;
let queue1;//设计它是为了指向current的updateQueue
let queue2; //设计它是为了指向alternate 的updateQueue
if (alternate === null) {//alternate为null,对于classcomponent第一次调用setState时alternate为null
// There's only one fiber.
queue1 = fiber.updateQueue;
queue2 = null;
if (queue1 === null) {//首次调用setState创建updateQueue,这时的memoizedState为初始值
queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState);
}
} else {
// There are two owners.
queue1 = fiber.updateQueue;//current Fiber updateQueue
queue2 = alternate.updateQueue;
if (queue1 === null) {
if (queue2 === null) {
// Neither fiber has an update queue. Create new ones.
//如果都为空,则分别创建,这个case我没有找到
queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState);
queue2 = alternate.updateQueue = createUpdateQueue(
alternate.memoizedState,
);
} else {
// Only one fiber has an update queue. Clone to create a new one.
// 如果有一个有update Queue,则克隆一个
queue1 = fiber.updateQueue = cloneUpdateQueue(queue2);
}
} else {
if (queue2 === null) {
// Only one fiber has an update queue. Clone to create a new one.
queue2 = alternate.updateQueue = cloneUpdateQueue(queue1);
} else {
// Both owners have an update queue.
}
}
}
if (queue2 === null || queue1 === queue2) {
// There's only a single queue.
//一般发生在首次 setState
appendUpdateToQueue(queue1, update);
} else {
// There are two queues. We need to append the update to both queues,
// while accounting for the persistent structure of the list — we don't
// want the same update to be added multiple times.
// 翻译:如果存在两个queues,我们需要追加这个 update到这个两个 queues.
//然而对于这种持久性结构的列表(updateQueue)需要保证一次update不能添加多次
if (queue1.lastUpdate === null || queue2.lastUpdate === null) {
// One of the queues is not empty. We must add the update to both queues.
appendUpdateToQueue(queue1, update);
appendUpdateToQueue(queue2, update);
} else {
// Both queues are non-empty. The last update is the same in both lists,
// because of structural sharing. So, only append to one of the lists.
appendUpdateToQueue(queue1, update);
// But we still need to update the `lastUpdate` pointer of queue2.
queue2.lastUpdate = update;
}
}
if (__DEV__) {
if (
fiber.tag === ClassComponent &&
(currentlyProcessingQueue === queue1 ||
(queue2 !== null && currentlyProcessingQueue === queue2)) &&
!didWarnUpdateInsideUpdate
) {
warningWithoutStack(
false,
'An update (setState, replaceState, or forceUpdate) was scheduled ' +
'from inside an update function. Update functions should be pure, ' +
'with zero side-effects. Consider using componentDidUpdate or a ' +
'callback.',
);
didWarnUpdateInsideUpdate = true;
}
}
}
updater
当前版本下updater下挂在了四个api
// react中打印this可见,最重要的就是enqueueSetState
updater:{
enqueueForceUpdate: ƒ (inst, callback)
enqueueReplaceState: ƒ (inst, payload, callback)
enqueueSetState: ƒ (inst, payload, callback)
isMounted: ƒ isMounted(component)
}
updater对象在整个react框架里是个单例。所有的update其实都是调用了这个对象的方法。