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的updateQueuelet queue2; //设计它是为了指向alternate 的updateQueueif (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 updateQueuequeue2 = 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.//一般发生在首次 setStateappendUpdateToQueue(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可见,最重要的就是enqueueSetStateupdater:{enqueueForceUpdate: ƒ (inst, callback)enqueueReplaceState: ƒ (inst, payload, callback)enqueueSetState: ƒ (inst, payload, callback)isMounted: ƒ isMounted(component)}
updater对象在整个react框架里是个单例。所有的update其实都是调用了这个对象的方法。
