Add Bailout effectTag for React DevTools (#9887)
* Add Bailout effectTag for React DevTools * Instead of tracking bailout, track performed work
Dan Abramov committed
Jun 8, 2017 at 21:23 UTC
a37012a6b5fb5a1c0c19c962737189aeaebe3684
3 files changed
+33
-14
src/renderers/shared/fiber/ReactFiberBeginWork.js
+13
-1
@@ -50,7 +50,13 @@ var {
50
Fragment,
51
} = ReactTypeOfWork;
52
var {NoWork, OffscreenPriority} = require('ReactPriorityLevel');
53
-var {Placement, ContentReset, Err, Ref} = require('ReactTypeOfSideEffect');
53
+var {
54
+ PerformedWork,
55
+ Placement,
56
+ ContentReset,
57
+ Err,
58
+ Ref,
59
+} = require('ReactTypeOfSideEffect');
60
var ReactFiberClassComponent = require('ReactFiberClassComponent');
61
var {ReactCurrentOwner} = require('ReactGlobalSharedState');
62
var invariant = require('fbjs/lib/invariant');
@@ -249,6 +255,8 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
255
} else {
256
nextChildren = fn(nextProps, context);
257
}
258
+ // React DevTools reads this flag.
259
+ workInProgress.effectTag |= PerformedWork;
260
reconcileChildren(current, workInProgress, nextChildren);
261
memoizeProps(workInProgress, nextProps);
262
return workInProgress.child;
@@ -315,6 +323,8 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
323
} else {
324
nextChildren = instance.render();
325
}
326
+ // React DevTools reads this flag.
327
+ workInProgress.effectTag |= PerformedWork;
328
reconcileChildren(current, workInProgress, nextChildren);
329
// Memoize props and state using the values we just used to render.
330
// TODO: Restructure so we never read values from the instance.
@@ -548,6 +558,8 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
558
} else {
559
value = fn(props, context);
560
}
561
+ // React DevTools reads this flag.
562
+ workInProgress.effectTag |= PerformedWork;
563
564
if (
565
typeof value === 'object' &&
src/renderers/shared/fiber/ReactFiberScheduler.js
+8
-4
@@ -64,7 +64,7 @@ var {
64
var {AsyncUpdates} = require('ReactTypeOfInternalContext');
65
66
var {
67
- NoEffect,
67
+ PerformedWork,
68
Placement,
69
Update,
70
PlacementAndUpdate,
@@ -335,7 +335,8 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
335
// updates, and deletions. To avoid needing to add a case for every
336
// possible bitmap value, we remove the secondary effects from the
337
// effect tag and switch on that value.
338
- let primaryEffectTag = effectTag & ~(Callback | Err | ContentReset | Ref);
338
+ let primaryEffectTag =
339
+ effectTag & ~(Callback | Err | ContentReset | Ref | PerformedWork);
340
switch (primaryEffectTag) {
341
case Placement: {
342
commitPlacement(nextEffect);
@@ -445,7 +446,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
446
priorityContext = TaskPriority;
447
448
let firstEffect;
448
- if (finishedWork.effectTag !== NoEffect) {
449
+ if (finishedWork.effectTag > PerformedWork) {
450
// A fiber's effect list consists only of its children, not itself. So if
451
// the root has an effect, we need to add it to the end of the list. The
452
// resulting list is the set that would belong to the root's parent, if
@@ -641,7 +642,10 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
642
// to schedule our own side-effect on our own list because if end up
643
// reusing children we'll schedule this effect onto itself since we're
644
// at the end.
644
- if (workInProgress.effectTag !== NoEffect) {
645
+ const effectTag = workInProgress.effectTag;
646
+ // Skip both NoWork and PerformedWork tags when creating the effect list.
647
+ // PerformedWork effect is read by React DevTools but shouldn't be committed.
648
+ if (effectTag > PerformedWork) {
649
if (returnFiber.lastEffect !== null) {
650
returnFiber.lastEffect.nextEffect = workInProgress;
651
} else {
src/renderers/shared/fiber/ReactTypeOfSideEffect.js
+12
-9
@@ -15,13 +15,16 @@
15
export type TypeOfSideEffect = number;
16
17
module.exports = {
18
- NoEffect: 0, // 0b0000000
19
- Placement: 1, // 0b0000001
20
- Update: 2, // 0b0000010
21
- PlacementAndUpdate: 3, // 0b0000011
22
- Deletion: 4, // 0b0000100
23
- ContentReset: 8, // 0b0001000
24
- Callback: 16, // 0b0010000
25
- Err: 32, // 0b0100000
26
- Ref: 64, // 0b1000000
18
+ // Don't change these two values:
19
+ NoEffect: 0, // 0b00000000
20
+ PerformedWork: 1, // 0b00000001
21
+ // You can change the rest (and add more).
22
+ Placement: 2, // 0b00000010
23
+ Update: 4, // 0b00000100
24
+ PlacementAndUpdate: 6, // 0b00000110
25
+ Deletion: 8, // 0b00001000
26
+ ContentReset: 16, // 0b00010000
27
+ Callback: 32, // 0b00100000
28
+ Err: 64, // 0b01000000
29
+ Ref: 128, // 0b10000000
30
};