You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
functionbatchedUpdates<A,R>(fn: A=>R,a: A): R{constprevExecutionContext=executionContext;executionContext|=BatchedContext;try{returnfn(a);}finally{executionContext=prevExecutionContext;if(executionContext===NoContext){// Flush the immediate callbacks that were scheduled during this batchflushSyncCallbackQueue();}}}
// scheduleUpdateOnFiber也就是scheduleWork (在enqueueSetState中调用)functionscheduleUpdateOnFiber(fiber: Fiber,lane: Lane,eventTime: number,){checkForNestedUpdates();warnAboutRenderPhaseUpdatesInDEV(fiber);constroot=markUpdateLaneFromFiberToRoot(fiber,lane);if(root===null){warnAboutUpdateOnUnmountedFiberInDEV(fiber);returnnull;}// TODO: requestUpdateLanePriority also reads the priority. Pass the// priority as an argument to that function and this one.constpriorityLevel=getCurrentPriorityLevel();if(lane===SyncLane){if(// 是否在unbatched update中(executionContext&LegacyUnbatchedContext)!==NoContext&&(executionContext&(RenderContext|CommitContext))===NoContext){schedulePendingInteractions(root,lane);performSyncWorkOnRoot(root);}else{ensureRootIsScheduled(root,eventTime);schedulePendingInteractions(root,lane);// setTimeout命中,触发flushSyncCallbackQueueif(executionContext===NoContext){flushSyncCallbackQueue();}}}else{if((executionContext&DiscreteEventContext)!==NoContext&&(priorityLevel===UserBlockingSchedulerPriority||priorityLevel===ImmediateSchedulerPriority)){if(rootsWithPendingDiscreteUpdates===null){rootsWithPendingDiscreteUpdates=newSet([root]);}else{rootsWithPendingDiscreteUpdates.add(root);}}ensureRootIsScheduled(root,eventTime);schedulePendingInteractions(root,lane);}mostRecentlyUpdatedRoot=root;}
记录下这么一个问题:React 中 setState 什么时候是同步的,什么时候是异步的?
这里的异步并不是异步执行,而是React会把多个setState合并更新
现象
直接上代码
上面代码注释有五种setState。下面来看一下log:
五种setState在每次调用this.setState后的console.log中,只有setTimeout中的this.setState是每次都可以拿到最新的state的,其余都是原始的state值。
再来看一下屏幕上render的结果:
只有在setState中使用function 和 在setTimeout中的setState 才会根据上一次的state来产生state,其余都是用了原始值作为base state
原因
出现上面现象的原因主要有:
什么是React batched update 机制
在之前版本的React中会有一个isBatchingUpdates变量,当isBatchingUpdates 为true的时候会产生批量更新的效果(放到队列中),当isBatchingUpdates为false的时候会直接产生更新。比如在之前版本的React的unstable_batchedUpdates实现
在当前最新版本的React(16.13.1)中unstable_batchedUpdates的实现:
可以看到React已经去掉了isBatchingUpdates,换成了executionContext这个枚举值
然后再看当在setTimeout中setState的时候executionContext会变成0 (枚举值NoContext):
总结setState合并执行
The text was updated successfully, but these errors were encountered: