Add Bailout effectTag for React DevTools (#9887)

* Add Bailout effectTag for React DevTools

* Instead of tracking bailout, track performed work
This commit is contained in:
Dan Abramov
2017-06-08 21:23:34 +01:00
committed by GitHub
parent 6ab0531d68
commit a37012a6b5
3 changed files with 33 additions and 14 deletions
@@ -50,7 +50,13 @@ var {
Fragment,
} = ReactTypeOfWork;
var {NoWork, OffscreenPriority} = require('ReactPriorityLevel');
var {Placement, ContentReset, Err, Ref} = require('ReactTypeOfSideEffect');
var {
PerformedWork,
Placement,
ContentReset,
Err,
Ref,
} = require('ReactTypeOfSideEffect');
var ReactFiberClassComponent = require('ReactFiberClassComponent');
var {ReactCurrentOwner} = require('ReactGlobalSharedState');
var invariant = require('fbjs/lib/invariant');
@@ -249,6 +255,8 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
} else {
nextChildren = fn(nextProps, context);
}
// React DevTools reads this flag.
workInProgress.effectTag |= PerformedWork;
reconcileChildren(current, workInProgress, nextChildren);
memoizeProps(workInProgress, nextProps);
return workInProgress.child;
@@ -315,6 +323,8 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
} else {
nextChildren = instance.render();
}
// React DevTools reads this flag.
workInProgress.effectTag |= PerformedWork;
reconcileChildren(current, workInProgress, nextChildren);
// Memoize props and state using the values we just used to render.
// 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>(
} else {
value = fn(props, context);
}
// React DevTools reads this flag.
workInProgress.effectTag |= PerformedWork;
if (
typeof value === 'object' &&
@@ -64,7 +64,7 @@ var {
var {AsyncUpdates} = require('ReactTypeOfInternalContext');
var {
NoEffect,
PerformedWork,
Placement,
Update,
PlacementAndUpdate,
@@ -335,7 +335,8 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
// updates, and deletions. To avoid needing to add a case for every
// possible bitmap value, we remove the secondary effects from the
// effect tag and switch on that value.
let primaryEffectTag = effectTag & ~(Callback | Err | ContentReset | Ref);
let primaryEffectTag =
effectTag & ~(Callback | Err | ContentReset | Ref | PerformedWork);
switch (primaryEffectTag) {
case Placement: {
commitPlacement(nextEffect);
@@ -445,7 +446,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
priorityContext = TaskPriority;
let firstEffect;
if (finishedWork.effectTag !== NoEffect) {
if (finishedWork.effectTag > PerformedWork) {
// A fiber's effect list consists only of its children, not itself. So if
// the root has an effect, we need to add it to the end of the list. The
// 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>(
// to schedule our own side-effect on our own list because if end up
// reusing children we'll schedule this effect onto itself since we're
// at the end.
if (workInProgress.effectTag !== NoEffect) {
const effectTag = workInProgress.effectTag;
// Skip both NoWork and PerformedWork tags when creating the effect list.
// PerformedWork effect is read by React DevTools but shouldn't be committed.
if (effectTag > PerformedWork) {
if (returnFiber.lastEffect !== null) {
returnFiber.lastEffect.nextEffect = workInProgress;
} else {
@@ -15,13 +15,16 @@
export type TypeOfSideEffect = number;
module.exports = {
NoEffect: 0, // 0b0000000
Placement: 1, // 0b0000001
Update: 2, // 0b0000010
PlacementAndUpdate: 3, // 0b0000011
Deletion: 4, // 0b0000100
ContentReset: 8, // 0b0001000
Callback: 16, // 0b0010000
Err: 32, // 0b0100000
Ref: 64, // 0b1000000
// Don't change these two values:
NoEffect: 0, // 0b00000000
PerformedWork: 1, // 0b00000001
// You can change the rest (and add more).
Placement: 2, // 0b00000010
Update: 4, // 0b00000100
PlacementAndUpdate: 6, // 0b00000110
Deletion: 8, // 0b00001000
ContentReset: 16, // 0b00010000
Callback: 32, // 0b00100000
Err: 64, // 0b01000000
Ref: 128, // 0b10000000
};