Updates should use the same priority context as top-level render
A bit of restructuring so that setState uses whatever the current priority context is, like top-level render already does. Renamed defaultPriority to priorityContext, and added a new variable called defaultPriorityContext. Having two separate variables allows the default to be changed without interfering with the current context.
Andrew Clark committed
Oct 28, 2016 at 11:26 UTC
7b9ae92058150494d372cfe17a8c086a307ee677
3 files changed
+45
-22
src/renderers/shared/fiber/ReactFiberBeginWork.js
+1
-1
@@ -48,7 +48,7 @@ var ReactFiberClassComponent = require('ReactFiberClassComponent');
48
49
module.exports = function<T, P, I, TI, C>(
50
config : HostConfig<T, P, I, TI, C>,
51
- scheduleUpdate : (fiber: Fiber, priorityLevel : PriorityLevel) => void
51
+ scheduleUpdate : (fiber: Fiber, priorityLevel : ?PriorityLevel) => void
52
) {
53
54
const {
src/renderers/shared/fiber/ReactFiberClassComponent.js
+6
-7
@@ -16,7 +16,6 @@ import type { Fiber } from 'ReactFiber';
16
import type { PriorityLevel } from 'ReactPriorityLevel';
17
import type { UpdateQueue } from 'ReactFiberUpdateQueue';
18
19
-var { LowPriority } = require('ReactPriorityLevel');
19
var {
20
createUpdateQueue,
21
addToQueue,
@@ -27,16 +26,16 @@ var { isMounted } = require('ReactFiberTreeReflection');
26
var ReactInstanceMap = require('ReactInstanceMap');
27
var shallowEqual = require('shallowEqual');
28
30
-module.exports = function(scheduleUpdate : (fiber: Fiber, priorityLevel : PriorityLevel) => void) {
29
+module.exports = function(scheduleUpdate : (fiber: Fiber, priorityLevel : ?PriorityLevel) => void) {
30
32
- function scheduleUpdateQueue(fiber: Fiber, updateQueue: UpdateQueue, priorityLevel : PriorityLevel) {
31
+ function scheduleUpdateQueue(fiber: Fiber, updateQueue: UpdateQueue) {
32
fiber.updateQueue = updateQueue;
33
// Schedule update on the alternate as well, since we don't know which tree
34
// is current.
35
if (fiber.alternate) {
36
fiber.alternate.updateQueue = updateQueue;
37
}
39
- scheduleUpdate(fiber, priorityLevel);
38
+ scheduleUpdate(fiber);
39
}
40
41
// Class component state updater
@@ -47,19 +46,19 @@ module.exports = function(scheduleUpdate : (fiber: Fiber, priorityLevel : Priori
46
const updateQueue = fiber.updateQueue ?
47
addToQueue(fiber.updateQueue, partialState) :
48
createUpdateQueue(partialState);
50
- scheduleUpdateQueue(fiber, updateQueue, LowPriority);
49
+ scheduleUpdateQueue(fiber, updateQueue);
50
},
51
enqueueReplaceState(instance, state) {
52
const fiber = ReactInstanceMap.get(instance);
53
const updateQueue = createUpdateQueue(state);
54
updateQueue.isReplace = true;
56
- scheduleUpdateQueue(fiber, updateQueue, LowPriority);
55
+ scheduleUpdateQueue(fiber, updateQueue);
56
},
57
enqueueForceUpdate(instance) {
58
const fiber = ReactInstanceMap.get(instance);
59
const updateQueue = fiber.updateQueue || createUpdateQueue(null);
60
updateQueue.isForced = true;
62
- scheduleUpdateQueue(fiber, updateQueue, LowPriority);
61
+ scheduleUpdateQueue(fiber, updateQueue);
62
},
63
enqueueCallback(instance, callback) {
64
const fiber = ReactInstanceMap.get(instance);
src/renderers/shared/fiber/ReactFiberScheduler.js
+38
-14
@@ -63,8 +63,10 @@ module.exports = function<T, P, I, TI, C>(config : HostConfig<T, P, I, TI, C>) {
63
const scheduleAnimationCallback = config.scheduleAnimationCallback;
64
const scheduleDeferredCallback = config.scheduleDeferredCallback;
65
66
- // The default priority to use for updates.
67
- let defaultPriority : PriorityLevel = LowPriority;
66
+ // The priority level to use when scheduling an update.
67
+ let priorityContext : (PriorityLevel | null) = null;
68
+ // The priority level to use if there is no priority context.
69
+ let defaultPriorityContext : PriorityLevel = LowPriority;
70
71
// The next work in progress fiber that we're currently working on.
72
let nextUnitOfWork : ?Fiber = null;
@@ -485,7 +487,7 @@ module.exports = function<T, P, I, TI, C>(config : HostConfig<T, P, I, TI, C>) {
487
while (nextUnitOfWork &&
488
nextPriorityLevel === SynchronousPriority) {
489
nextUnitOfWork = performUnitOfWork(nextUnitOfWork, false);
488
- // If there's no nextUnitForWork, we don't need to search for more
490
+ // If there's no nextUnitOfWork, we don't need to search for more
491
// because it shouldn't be possible to schedule sync work without
492
// immediately performing it
493
}
@@ -591,23 +593,45 @@ module.exports = function<T, P, I, TI, C>(config : HostConfig<T, P, I, TI, C>) {
593
}
594
}
595
594
- function scheduleWork(root : FiberRoot) {
595
- if (defaultPriority === SynchronousPriority) {
596
+ function scheduleWork(root : FiberRoot, priorityLevel : ?PriorityLevel) {
597
+ if (priorityLevel == null) {
598
+ priorityLevel = priorityContext !== null ?
599
+ priorityContext :
600
+ defaultPriorityContext;
601
+ }
602
+
603
+ if (priorityLevel === SynchronousPriority) {
604
root.current.pendingWorkPriority = SynchronousPriority;
605
performSynchronousWork();
606
}
607
600
- if (defaultPriority === NoWork) {
608
+ if (priorityLevel === NoWork) {
609
return;
610
}
603
- if (defaultPriority > AnimationPriority) {
604
- scheduleDeferredWork(root, defaultPriority);
611
+ if (priorityLevel > AnimationPriority) {
612
+ scheduleDeferredWork(root, priorityLevel);
613
return;
614
}
607
- scheduleAnimationWork(root, defaultPriority);
615
+ scheduleAnimationWork(root, priorityLevel);
616
}
617
610
- function scheduleUpdate(fiber: Fiber, priorityLevel : PriorityLevel): void {
618
+ function scheduleUpdate(fiber: Fiber, priorityLevel : ?PriorityLevel): void {
619
+ // Use priority context if no priority is provided
620
+ if (priorityLevel == null) {
621
+ priorityLevel = priorityContext !== null ?
622
+ priorityContext :
623
+ defaultPriorityContext;
624
+ }
625
+
626
+ // Don't bother bubbling the priority to the root if it is synchronous. Just
627
+ // perform it now.
628
+ if (priorityLevel === SynchronousPriority) {
629
+ fiber.pendingWorkPriority = SynchronousPriority;
630
+ nextUnitOfWork = fiber;
631
+ performSynchronousWork();
632
+ return;
633
+ }
634
+
635
while (true) {
636
if (fiber.pendingWorkPriority === NoWork ||
637
fiber.pendingWorkPriority >= priorityLevel) {
@@ -622,7 +646,7 @@ module.exports = function<T, P, I, TI, C>(config : HostConfig<T, P, I, TI, C>) {
646
if (!fiber.return) {
647
if (fiber.tag === HostContainer) {
648
const root : FiberRoot = (fiber.stateNode : any);
625
- scheduleDeferredWork(root, priorityLevel);
649
+ scheduleWork(root, priorityLevel);
650
return;
651
} else {
652
throw new Error('Invalid root');
@@ -633,12 +657,12 @@ module.exports = function<T, P, I, TI, C>(config : HostConfig<T, P, I, TI, C>) {
657
}
658
659
function performWithPriority(priorityLevel : PriorityLevel, fn : Function) {
636
- const previousDefaultPriority = defaultPriority;
637
- defaultPriority = priorityLevel;
660
+ const previousPriorityContext = priorityContext;
661
+ priorityContext = priorityLevel;
662
try {
663
fn();
664
} finally {
641
- defaultPriority = previousDefaultPriority;
665
+ priorityContext = previousPriorityContext;
666
}
667
}
668