Use `T | null` instead of `?T` types
Flow maybe types accept both null and undefined. When the final parameter of a function accepts a maybe type, passing nothing (undefined) successfully typechecks, which can lead to bugs if the omission is accidental. Being forced to pass null is harder to screw up. Explicit null checks are also faster.
Andrew Clark committed
Feb 10, 2017 at 17:30 UTC
350d736361f5a86d94960cfd230ff7f77a21785b
12 files changed
+263
-271
src/renderers/shared/fiber/ReactChildFiber.js
+82
-86
@@ -73,9 +73,9 @@ const {
73
Deletion,
74
} = ReactTypeOfSideEffect;
75
76
-function coerceRef(current: ?Fiber, element: ReactElement) {
76
+function coerceRef(current: Fiber | null, element: ReactElement) {
77
let mixedRef = element.ref;
78
- if (mixedRef != null && typeof mixedRef !== 'function') {
78
+ if (mixedRef !== null && typeof mixedRef !== 'function') {
79
if (element._owner) {
80
const owner : ?(Fiber | ReactInstance) = (element._owner : any);
81
let inst;
@@ -97,7 +97,7 @@ function coerceRef(current: ?Fiber, element: ReactElement) {
97
);
98
const stringRef = String(mixedRef);
99
// Check if previous string ref matches new string ref
100
- if (current && current.ref && current.ref._stringRef === stringRef) {
100
+ if (current !== null && current.ref !== null && current.ref._stringRef === stringRef) {
101
return current.ref;
102
}
103
const ref = function(value) {
@@ -161,14 +161,14 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
161
// When we're reconciling in place we have a work in progress copy. We
162
// actually want the current copy. If there is no current copy, then we
163
// don't need to track deletion side-effects.
164
- if (!childToDelete.alternate) {
164
+ if (childToDelete.alternate === null) {
165
return;
166
}
167
childToDelete = childToDelete.alternate;
168
}
169
// Deletions are added in reversed order so we add it to the front.
170
const last = returnFiber.progressedLastDeletion;
171
- if (last) {
171
+ if (last !== null) {
172
last.nextEffect = childToDelete;
173
returnFiber.progressedLastDeletion = childToDelete;
174
} else {
@@ -182,7 +182,7 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
182
183
function deleteRemainingChildren(
184
returnFiber : Fiber,
185
- currentFirstChild : ?Fiber
185
+ currentFirstChild : Fiber | null
186
) : null {
187
if (!shouldTrackSideEffects) {
188
// Noop.
@@ -192,7 +192,7 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
192
// TODO: For the shouldClone case, this could be micro-optimized a bit by
193
// assuming that after the first child we've already added everything.
194
let childToDelete = currentFirstChild;
195
- while (childToDelete) {
195
+ while (childToDelete !== null) {
196
deleteChild(returnFiber, childToDelete);
197
childToDelete = childToDelete.sibling;
198
}
@@ -209,7 +209,7 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
209
const existingChildren : Map<string | number, Fiber> = new Map();
210
211
let existingChild = currentFirstChild;
212
- while (existingChild) {
212
+ while (existingChild !== null) {
213
if (existingChild.key !== null) {
214
existingChildren.set(existingChild.key, existingChild);
215
} else {
@@ -247,7 +247,7 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
247
return lastPlacedIndex;
248
}
249
const current = newFiber.alternate;
250
- if (current) {
250
+ if (current !== null) {
251
const oldIndex = current.index;
252
if (oldIndex < lastPlacedIndex) {
253
// This is a move.
@@ -267,7 +267,7 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
267
function placeSingleChild(newFiber : Fiber) : Fiber {
268
// This is simpler for the single child case. We only need to do a
269
// placement for inserting new children.
270
- if (shouldTrackSideEffects && !newFiber.alternate) {
270
+ if (shouldTrackSideEffects && newFiber.alternate === null) {
271
newFiber.effectTag = Placement;
272
}
273
return newFiber;
@@ -275,11 +275,11 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
275
276
function updateTextNode(
277
returnFiber : Fiber,
278
- current : ?Fiber,
278
+ current : Fiber | null,
279
textContent : string,
280
priority : PriorityLevel
281
) {
282
- if (current == null || current.tag !== HostText) {
282
+ if (current === null || current.tag !== HostText) {
283
// Insert
284
const created = createFiberFromText(textContent, priority);
285
created.return = returnFiber;
@@ -295,11 +295,11 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
295
296
function updateElement(
297
returnFiber : Fiber,
298
- current : ?Fiber,
298
+ current : Fiber | null,
299
element : ReactElement,
300
priority : PriorityLevel
301
) : Fiber {
302
- if (current == null || current.type !== element.type) {
302
+ if (current === null || current.type !== element.type) {
303
// Insert
304
const created = createFiberFromElement(element, priority);
305
created.ref = coerceRef(current, element);
@@ -321,12 +321,12 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
321
322
function updateCoroutine(
323
returnFiber : Fiber,
324
- current : ?Fiber,
324
+ current : Fiber | null,
325
coroutine : ReactCoroutine,
326
priority : PriorityLevel
327
) : Fiber {
328
// TODO: Should this also compare handler to determine whether to reuse?
329
- if (current == null || current.tag !== CoroutineComponent) {
329
+ if (current === null || current.tag !== CoroutineComponent) {
330
// Insert
331
const created = createFiberFromCoroutine(coroutine, priority);
332
created.return = returnFiber;
@@ -342,11 +342,11 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
342
343
function updateYield(
344
returnFiber : Fiber,
345
- current : ?Fiber,
345
+ current : Fiber | null,
346
yieldNode : ReactYield,
347
priority : PriorityLevel
348
) : Fiber {
349
- if (current == null || current.tag !== YieldComponent) {
349
+ if (current === null || current.tag !== YieldComponent) {
350
// Insert
351
const created = createFiberFromYield(yieldNode, priority);
352
created.type = yieldNode.value;
@@ -363,12 +363,12 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
363
364
function updatePortal(
365
returnFiber : Fiber,
366
- current : ?Fiber,
366
+ current : Fiber | null,
367
portal : ReactPortal,
368
priority : PriorityLevel
369
) : Fiber {
370
if (
371
- current == null ||
371
+ current === null ||
372
current.tag !== HostPortal ||
373
current.stateNode.containerInfo !== portal.containerInfo ||
374
current.stateNode.implementation !== portal.implementation
@@ -388,11 +388,11 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
388
389
function updateFragment(
390
returnFiber : Fiber,
391
- current : ?Fiber,
391
+ current : Fiber | null,
392
fragment : Iterable<*>,
393
priority : PriorityLevel
394
) : Fiber {
395
- if (current == null || current.tag !== Fragment) {
395
+ if (current === null || current.tag !== Fragment) {
396
// Insert
397
const created = createFiberFromFragment(fragment, priority);
398
created.return = returnFiber;
@@ -410,7 +410,7 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
410
returnFiber : Fiber,
411
newChild : any,
412
priority : PriorityLevel
413
- ) : ?Fiber {
413
+ ) : Fiber | null {
414
if (typeof newChild === 'string' || typeof newChild === 'number') {
415
// Text nodes doesn't have keys. If the previous node is implicitly keyed
416
// we can continue to replace it without aborting even if it is not a text
@@ -463,13 +463,13 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
463
464
function updateSlot(
465
returnFiber : Fiber,
466
- oldFiber : ?Fiber,
466
+ oldFiber : Fiber | null,
467
newChild : any,
468
priority : PriorityLevel
469
- ) : ?Fiber {
469
+ ) : Fiber | null {
470
// Update the fiber if the keys match, otherwise return null.
471
472
- const key = oldFiber ? oldFiber.key : null;
472
+ const key = oldFiber !== null ? oldFiber.key : null;
473
474
if (typeof newChild === 'string' || typeof newChild === 'number') {
475
// Text nodes doesn't have keys. If the previous node is implicitly keyed
@@ -540,7 +540,7 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
540
newIdx : number,
541
newChild : any,
542
priority : PriorityLevel
543
- ) : ?Fiber {
543
+ ) : Fiber | null {
544
545
if (typeof newChild === 'string' || typeof newChild === 'number') {
546
// Text nodes doesn't have keys, so we neither have to check the old nor
@@ -596,7 +596,7 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
596
knownKeys : Set<string> | null
597
) : Set<string> | null {
598
if (__DEV__) {
599
- if (typeof child !== 'object' || child == null) {
599
+ if (typeof child !== 'object' || child === null) {
600
return knownKeys;
601
}
602
switch (child.$$typeof) {
@@ -607,7 +607,7 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
607
if (typeof key !== 'string') {
608
break;
609
}
610
- if (knownKeys == null) {
610
+ if (knownKeys === null) {
611
knownKeys = new Set();
612
knownKeys.add(key);
613
break;
@@ -634,9 +634,9 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
634
635
function reconcileChildrenArray(
636
returnFiber : Fiber,
637
- currentFirstChild : ?Fiber,
637
+ currentFirstChild : Fiber | null,
638
newChildren : Array<*>,
639
- priority : PriorityLevel) : ?Fiber {
639
+ priority : PriorityLevel) : Fiber | null {
640
641
// This algorithm can't optimize by searching from boths ends since we
642
// don't have backpointers on fibers. I'm trying to see how far we can get
@@ -666,21 +666,19 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
666
}
667
}
668
669
- let resultingFirstChild : ?Fiber = null;
670
- let previousNewFiber : ?Fiber = null;
669
+ let resultingFirstChild : Fiber | null = null;
670
+ let previousNewFiber : Fiber | null = null;
671
672
let oldFiber = currentFirstChild;
673
let lastPlacedIndex = 0;
674
let newIdx = 0;
675
let nextOldFiber = null;
676
- for (; oldFiber && newIdx < newChildren.length; newIdx++) {
677
- if (oldFiber) {
678
- if (oldFiber.index > newIdx) {
679
- nextOldFiber = oldFiber;
680
- oldFiber = null;
681
- } else {
682
- nextOldFiber = oldFiber.sibling;
683
- }
676
+ for (; oldFiber !== null && newIdx < newChildren.length; newIdx++) {
677
+ if (oldFiber.index > newIdx) {
678
+ nextOldFiber = oldFiber;
679
+ oldFiber = null;
680
+ } else {
681
+ nextOldFiber = oldFiber.sibling;
682
}
683
const newFiber = updateSlot(
684
returnFiber,
@@ -688,25 +686,25 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
686
newChildren[newIdx],
687
priority
688
);
691
- if (!newFiber) {
689
+ if (newFiber === null) {
690
// TODO: This breaks on empty slots like null children. That's
691
// unfortunate because it triggers the slow path all the time. We need
692
// a better way to communicate whether this was a miss or null,
693
// boolean, undefined, etc.
696
- if (!oldFiber) {
694
+ if (oldFiber === null) {
695
oldFiber = nextOldFiber;
696
}
697
break;
698
}
699
if (shouldTrackSideEffects) {
702
- if (oldFiber && !newFiber.alternate) {
700
+ if (oldFiber && newFiber.alternate === null) {
701
// We matched the slot, but we didn't reuse the existing fiber, so we
702
// need to delete the existing child.
703
deleteChild(returnFiber, oldFiber);
704
}
705
}
706
lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
709
- if (!previousNewFiber) {
707
+ if (previousNewFiber === null) {
708
// TODO: Move out of the loop. This only happens for the first run.
709
resultingFirstChild = newFiber;
710
} else {
@@ -726,7 +724,7 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
724
return resultingFirstChild;
725
}
726
729
- if (!oldFiber) {
727
+ if (oldFiber === null) {
728
// If we don't have any more existing children we can choose a fast path
729
// since the rest will all be insertions.
730
for (; newIdx < newChildren.length; newIdx++) {
@@ -739,7 +737,7 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
737
continue;
738
}
739
lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
742
- if (!previousNewFiber) {
740
+ if (previousNewFiber === null) {
741
// TODO: Move out of the loop. This only happens for the first run.
742
resultingFirstChild = newFiber;
743
} else {
@@ -764,7 +762,7 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
762
);
763
if (newFiber) {
764
if (shouldTrackSideEffects) {
767
- if (newFiber.alternate) {
765
+ if (newFiber.alternate !== null) {
766
// The new fiber is a work in progress, but if there exists a
767
// current, that means that we reused the fiber. We need to delete
768
// it from the child list so that we don't add it to the deletion
@@ -775,7 +773,7 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
773
}
774
}
775
lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
778
- if (!previousNewFiber) {
776
+ if (previousNewFiber === null) {
777
resultingFirstChild = newFiber;
778
} else {
779
previousNewFiber.sibling = newFiber;
@@ -795,9 +793,9 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
793
794
function reconcileChildrenIterator(
795
returnFiber : Fiber,
798
- currentFirstChild : ?Fiber,
796
+ currentFirstChild : Fiber | null,
797
newChildrenIterable : Iterable<*>,
800
- priority : PriorityLevel) : ?Fiber {
798
+ priority : PriorityLevel) : Fiber | null {
799
800
// This is the same implementation as reconcileChildrenArray(),
801
// but using the iterator instead.
@@ -852,8 +850,8 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
850
'An iterable object provided no iterator.',
851
);
852
855
- let resultingFirstChild : ?Fiber = null;
856
- let previousNewFiber : ?Fiber = null;
853
+ let resultingFirstChild : Fiber | null = null;
854
+ let previousNewFiber : Fiber | null = null;
855
856
let oldFiber = currentFirstChild;
857
let lastPlacedIndex = 0;
@@ -861,14 +859,12 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
859
let nextOldFiber = null;
860
861
let step = newChildren.next();
864
- for (; oldFiber && !step.done; newIdx++, step = newChildren.next()) {
865
- if (oldFiber) {
866
- if (oldFiber.index > newIdx) {
867
- nextOldFiber = oldFiber;
868
- oldFiber = null;
869
- } else {
870
- nextOldFiber = oldFiber.sibling;
871
- }
862
+ for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next()) {
863
+ if (oldFiber.index > newIdx) {
864
+ nextOldFiber = oldFiber;
865
+ oldFiber = null;
866
+ } else {
867
+ nextOldFiber = oldFiber.sibling;
868
}
869
const newFiber = updateSlot(
870
returnFiber,
@@ -876,7 +872,7 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
872
step.value,
873
priority
874
);
879
- if (!newFiber) {
875
+ if (newFiber === null) {
876
// TODO: This breaks on empty slots like null children. That's
877
// unfortunate because it triggers the slow path all the time. We need
878
// a better way to communicate whether this was a miss or null,
@@ -887,14 +883,14 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
883
break;
884
}
885
if (shouldTrackSideEffects) {
890
- if (oldFiber && !newFiber.alternate) {
886
+ if (oldFiber && newFiber.alternate === null) {
887
// We matched the slot, but we didn't reuse the existing fiber, so we
888
// need to delete the existing child.
889
deleteChild(returnFiber, oldFiber);
890
}
891
}
892
lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
897
- if (!previousNewFiber) {
893
+ if (previousNewFiber === null) {
894
// TODO: Move out of the loop. This only happens for the first run.
895
resultingFirstChild = newFiber;
896
} else {
@@ -914,7 +910,7 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
910
return resultingFirstChild;
911
}
912
917
- if (!oldFiber) {
913
+ if (oldFiber === null) {
914
// If we don't have any more existing children we can choose a fast path
915
// since the rest will all be insertions.
916
for (; !step.done; newIdx++, step = newChildren.next()) {
@@ -923,11 +919,11 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
919
step.value,
920
priority
921
);
926
- if (!newFiber) {
922
+ if (newFiber === null) {
923
continue;
924
}
925
lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
930
- if (!previousNewFiber) {
926
+ if (previousNewFiber === null) {
927
// TODO: Move out of the loop. This only happens for the first run.
928
resultingFirstChild = newFiber;
929
} else {
@@ -950,9 +946,9 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
946
step.value,
947
priority
948
);
953
- if (newFiber) {
949
+ if (newFiber !== null) {
950
if (shouldTrackSideEffects) {
955
- if (newFiber.alternate) {
951
+ if (newFiber.alternate !== null) {
952
// The new fiber is a work in progress, but if there exists a
953
// current, that means that we reused the fiber. We need to delete
954
// it from the child list so that we don't add it to the deletion
@@ -963,7 +959,7 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
959
}
960
}
961
lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
966
- if (!previousNewFiber) {
962
+ if (previousNewFiber === null) {
963
resultingFirstChild = newFiber;
964
} else {
965
previousNewFiber.sibling = newFiber;
@@ -983,13 +979,13 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
979
980
function reconcileSingleTextNode(
981
returnFiber : Fiber,
986
- currentFirstChild : ?Fiber,
982
+ currentFirstChild : Fiber | null,
983
textContent : string,
984
priority : PriorityLevel
985
) : Fiber {
986
// There's no need to check for keys on text nodes since we don't have a
987
// way to define them.
992
- if (currentFirstChild && currentFirstChild.tag === HostText) {
988
+ if (currentFirstChild !== null && currentFirstChild.tag === HostText) {
989
// We already have an existing node so let's just update it and delete
990
// the rest.
991
deleteRemainingChildren(returnFiber, currentFirstChild.sibling);
@@ -1008,13 +1004,13 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
1004
1005
function reconcileSingleElement(
1006
returnFiber : Fiber,
1011
- currentFirstChild : ?Fiber,
1007
+ currentFirstChild : Fiber | null,
1008
element : ReactElement,
1009
priority : PriorityLevel
1010
) : Fiber {
1011
const key = element.key;
1012
let child = currentFirstChild;
1017
- while (child) {
1013
+ while (child !== null) {
1014
// TODO: If key === null and child.key === null, then this only applies to
1015
// the first item in the list.
1016
if (child.key === key) {
@@ -1047,13 +1043,13 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
1043
1044
function reconcileSingleCoroutine(
1045
returnFiber : Fiber,
1050
- currentFirstChild : ?Fiber,
1046
+ currentFirstChild : Fiber | null,
1047
coroutine : ReactCoroutine,
1048
priority : PriorityLevel
1049
) : Fiber {
1050
const key = coroutine.key;
1051
let child = currentFirstChild;
1056
- while (child) {
1052
+ while (child !== null) {
1053
// TODO: If key === null and child.key === null, then this only applies to
1054
// the first item in the list.
1055
if (child.key === key) {
@@ -1080,13 +1076,13 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
1076
1077
function reconcileSingleYield(
1078
returnFiber : Fiber,
1083
- currentFirstChild : ?Fiber,
1079
+ currentFirstChild : Fiber | null,
1080
yieldNode : ReactYield,
1081
priority : PriorityLevel
1082
) : Fiber {
1083
// There's no need to check for keys on yields since they're stateless.
1084
let child = currentFirstChild;
1089
- if (child) {
1085
+ if (child !== null) {
1086
if (child.tag === YieldComponent) {
1087
deleteRemainingChildren(returnFiber, child.sibling);
1088
const existing = useFiber(child, priority);
@@ -1106,13 +1102,13 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
1102
1103
function reconcileSinglePortal(
1104
returnFiber : Fiber,
1109
- currentFirstChild : ?Fiber,
1105
+ currentFirstChild : Fiber | null,
1106
portal : ReactPortal,
1107
priority : PriorityLevel
1108
) : Fiber {
1109
const key = portal.key;
1110
let child = currentFirstChild;
1115
- while (child) {
1111
+ while (child !== null) {
1112
// TODO: If key === null and child.key === null, then this only applies to
1113
// the first item in the list.
1114
if (child.key === key) {
@@ -1146,10 +1142,10 @@ function ChildReconciler(shouldClone, shouldTrackSideEffects) {
1142
// children and the parent.
1143
function reconcileChildFibers(
1144
returnFiber : Fiber,
1149
- currentFirstChild : ?Fiber,
1145
+ currentFirstChild : Fiber | null,
1146
newChild : any,
1147
priority : PriorityLevel
1152
- ) : ?Fiber {
1148
+ ) : Fiber | null {
1149
// This function is not recursive.
1150
// If the top level item is an array, we treat it as a set of children,
1151
// not as a fragment. Nested arrays on the other hand will be treated as
@@ -1329,11 +1325,11 @@ exports.reconcileChildFibersInPlace = ChildReconciler(false, true);
1325
1326
exports.mountChildFibersInPlace = ChildReconciler(false, false);
1327
1332
-exports.cloneChildFibers = function(current : ?Fiber, workInProgress : Fiber) : void {
1328
+exports.cloneChildFibers = function(current : Fiber | null, workInProgress : Fiber) : void {
1329
if (!workInProgress.child) {
1330
return;
1331
}
1336
- if (current && workInProgress.child === current.child) {
1332
+ if (current !== null && workInProgress.child === current.child) {
1333
// We use workInProgress.child since that lets Flow know that it can't be
1334
// null since we validated that already. However, as the line above suggests
1335
// they're actually the same thing.
@@ -1349,7 +1345,7 @@ exports.cloneChildFibers = function(current : ?Fiber, workInProgress : Fiber) :
1345
workInProgress.child = newChild;
1346
1347
newChild.return = workInProgress;
1352
- while (currentChild.sibling) {
1348
+ while (currentChild.sibling !== null) {
1349
currentChild = currentChild.sibling;
1350
newChild = newChild.sibling = cloneFiber(
1351
currentChild,
@@ -1365,7 +1361,7 @@ exports.cloneChildFibers = function(current : ?Fiber, workInProgress : Fiber) :
1361
// need to clone. We need to reset the return fiber though since we'll
1362
// traverse down into them.
1363
let child = workInProgress.child;
1368
- while (child) {
1364
+ while (child !== null) {
1365
child.return = workInProgress;
1366
child = child.sibling;
1367
}
src/renderers/shared/fiber/ReactDebugCurrentFiber.js
+2
-2
@@ -22,7 +22,7 @@ if (__DEV__) {
22
function getCurrentFiberOwnerName() : string | null {
23
if (__DEV__) {
24
const fiber = ReactDebugCurrentFiber.current;
25
- if (fiber == null) {
25
+ if (fiber === null) {
26
return null;
27
}
28
if (fiber._debugOwner != null) {
@@ -35,7 +35,7 @@ function getCurrentFiberOwnerName() : string | null {
35
function getCurrentFiberStackAddendum() : string | null {
36
if (__DEV__) {
37
const fiber = ReactDebugCurrentFiber.current;
38
- if (fiber == null) {
38
+ if (fiber === null) {
39
return null;
40
}
41
// Safe because if current fiber exists, we are reconciling,
src/renderers/shared/fiber/ReactFiber.js
+11
-11
@@ -93,11 +93,11 @@ export type Fiber = {
93
// This is effectively the parent, but there can be multiple parents (two)
94
// so this is only the parent of the thing we're currently processing.
95
// It is conceptually the same as the return address of a stack frame.
96
- return: ?Fiber,
96
+ return: Fiber | null,
97
98
// Singly Linked List Tree Structure.
99
- child: ?Fiber,
100
- sibling: ?Fiber,
99
+ child: Fiber | null,
100
+ sibling: Fiber | null,
101
index: number,
102
103
// The ref last used to attach this node.
@@ -119,13 +119,13 @@ export type Fiber = {
119
effectTag: TypeOfSideEffect,
120
121
// Singly linked list fast path to the next fiber with side-effects.
122
- nextEffect: ?Fiber,
122
+ nextEffect: Fiber | null,
123
124
// The first and last fiber with side-effect within this subtree. This allows
125
// us to reuse a slice of the linked list when we reuse the work done within
126
// this fiber.
127
- firstEffect: ?Fiber,
128
- lastEffect: ?Fiber,
127
+ firstEffect: Fiber | null,
128
+ lastEffect: Fiber | null,
129
130
// This will be used to quickly determine if a subtree has no pending changes.
131
pendingWorkPriority: PriorityLevel,
@@ -139,19 +139,19 @@ export type Fiber = {
139
// priority, then we need to store the progressed work somewhere. This holds
140
// the started child set until we need to get back to working on it. It may
141
// or may not be the same as the "current" child.
142
- progressedChild: ?Fiber,
142
+ progressedChild: Fiber | null,
143
144
// When we reconcile children onto progressedChild it is possible that we have
145
// to delete some child fibers. We need to keep track of this side-effects so
146
// that if we continue later on, we have to include those effects. Deletions
147
// are added in the reverse order from sibling pointers.
148
- progressedFirstDeletion: ?Fiber,
149
- progressedLastDeletion: ?Fiber,
148
+ progressedFirstDeletion: Fiber | null,
149
+ progressedLastDeletion: Fiber | null,
150
151
// This is a pooled version of a Fiber. Every fiber that gets updated will
152
// eventually have a pair. There are cases when we can clean up pairs to save
153
// memory if we need to.
154
- alternate: ?Fiber,
154
+ alternate: Fiber | null,
155
156
// Conceptual aliases
157
// workInProgress : Fiber -> alternate The alternate used for reuse happens
@@ -249,7 +249,7 @@ exports.cloneFiber = function(fiber : Fiber, priorityLevel : PriorityLevel) : Fi
249
// objects for things that are never updated. It also allow us to reclaim the
250
// extra memory if needed.
251
let alt = fiber.alternate;
252
- if (alt) {
252
+ if (alt !== null) {
253
// If we clone, then we do so from the "current" state. The current state
254
// can't have any side-effects that are still valid so we reset just to be
255
// sure.
src/renderers/shared/fiber/ReactFiberBeginWork.js
+22
-22
@@ -102,7 +102,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
102
// We now have clones. Let's store them as the currently progressed work.
103
workInProgress.progressedChild = workInProgress.child;
104
workInProgress.progressedPriority = priorityLevel;
105
- if (current) {
105
+ if (current !== null) {
106
// We also store it on the current. When the alternate swaps in we can
107
// continue from this point.
108
current.progressedChild = workInProgress.progressedChild;
@@ -131,7 +131,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
131
// At this point any memoization is no longer valid since we'll have changed
132
// the children.
133
workInProgress.memoizedProps = null;
134
- if (!current) {
134
+ if (current === null) {
135
// If this is a fresh new component that hasn't been rendered yet, we
136
// won't update its child set by applying minimal side-effects. Instead,
137
// we will add them all to the child before it gets rendered. That means
@@ -191,9 +191,9 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
191
return workInProgress.child;
192
}
193
194
- function markRef(current : ?Fiber, workInProgress : Fiber) {
194
+ function markRef(current : Fiber | null, workInProgress : Fiber) {
195
const ref = workInProgress.ref;
196
- if (ref && (!current || current.ref !== ref)) {
196
+ if (ref !== null && (!current || current.ref !== ref)) {
197
// Schedule a Ref effect
198
workInProgress.effectTag |= Ref;
199
}
@@ -211,7 +211,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
211
nextProps = memoizedProps;
212
}
213
} else {
214
- if (nextProps == null || memoizedProps === nextProps) {
214
+ if (nextProps === null || memoizedProps === nextProps) {
215
return bailoutOnAlreadyFinishedWork(current, workInProgress);
216
}
217
// TODO: Disable this before release, since it is not part of the public API
@@ -240,14 +240,14 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
240
return workInProgress.child;
241
}
242
243
- function updateClassComponent(current : ?Fiber, workInProgress : Fiber, priorityLevel : PriorityLevel) {
243
+ function updateClassComponent(current : Fiber | null, workInProgress : Fiber, priorityLevel : PriorityLevel) {
244
// Push context providers early to prevent context stack mismatches.
245
// During mounting we don't know the child context yet as the instance doesn't exist.
246
// We will invalidate the child context in finishClassComponent() right after rendering.
247
const hasContext = pushContextProvider(workInProgress);
248
249
let shouldUpdate;
250
- if (!current) {
250
+ if (current === null) {
251
if (!workInProgress.stateNode) {
252
// In the initial pass we might need to construct the instance.
253
constructClassInstance(workInProgress);
@@ -264,7 +264,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
264
}
265
266
function finishClassComponent(
267
- current : ?Fiber,
267
+ current : Fiber | null,
268
workInProgress : Fiber,
269
shouldUpdate : boolean,
270
hasContext : boolean,
@@ -314,7 +314,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
314
pushHostContainer(workInProgress, root.containerInfo);
315
316
const updateQueue = workInProgress.updateQueue;
317
- if (updateQueue) {
317
+ if (updateQueue !== null) {
318
const prevState = workInProgress.memoizedState;
319
const state = beginUpdateQueue(workInProgress, updateQueue, null, prevState, null, priorityLevel);
320
if (prevState === state) {
@@ -335,7 +335,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
335
pushHostContext(workInProgress);
336
337
let nextProps = workInProgress.pendingProps;
338
- const prevProps = current ? current.memoizedProps : null;
338
+ const prevProps = current !== null ? current.memoizedProps : null;
339
const memoizedProps = workInProgress.memoizedProps;
340
if (hasContextChanged()) {
341
// Normally we can bail out on props equality but if context has changed
@@ -359,7 +359,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
359
// that is a bit tricky since workInProgress and current can have
360
// different "hidden" settings.
361
let child = workInProgress.progressedChild;
362
- while (child) {
362
+ while (child !== null) {
363
// To ensure that this subtree gets its priority reset, the children
364
// need to be reset.
365
child.pendingWorkPriority = OffscreenPriority;
@@ -409,16 +409,16 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
409
// Reconcile the children and stash them for later work.
410
reconcileChildrenAtPriority(current, workInProgress, nextChildren, OffscreenPriority);
411
memoizeProps(workInProgress, nextProps);
412
- workInProgress.child = current ? current.child : null;
412
+ workInProgress.child = current !== null ? current.child : null;
413
414
- if (!current) {
414
+ if (current === null) {
415
// If this doesn't have a current we won't track it for placement
416
// effects. However, when we come back around to this we have already
417
// inserted the parent which means that we'll infact need to make this a
418
// placement.
419
// TODO: There has to be a better solution to this problem.
420
let child = workInProgress.progressedChild;
421
- while (child) {
421
+ while (child !== null) {
422
child.effectTag = Placement;
423
child = child.sibling;
424
}
@@ -464,7 +464,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
464
value = fn(props, context);
465
}
466
467
- if (typeof value === 'object' && value && typeof value.render === 'function') {
467
+ if (typeof value === 'object' && value !== null && typeof value.render === 'function') {
468
// Proceed under the assumption that this is a class instance
469
workInProgress.tag = ClassComponent;
470
@@ -479,7 +479,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
479
// Proceed under the assumption that this is a functional component
480
workInProgress.tag = FunctionalComponent;
481
if (__DEV__) {
482
- if (workInProgress.ref != null) {
482
+ if (workInProgress.ref !== null) {
483
let info = '';
484
const ownerName = ReactDebugCurrentFiber.getCurrentFiberOwnerName();
485
if (ownerName) {
@@ -517,7 +517,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
517
if (nextCoroutine === null) {
518
nextCoroutine = current && current.memoizedProps;
519
invariant(
520
- nextCoroutine != null,
520
+ nextCoroutine !== null,
521
'We should always have pending or current props. This error is ' +
522
'likely caused by a bug in React. Please file an issue.'
523
);
@@ -538,7 +538,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
538
// At this point any memoization is no longer valid since we'll have changed
539
// the children.
540
workInProgress.memoizedProps = null;
541
- if (!current) {
541
+ if (current === null) {
542
workInProgress.stateNode = mountChildFibersInPlace(
543
workInProgress,
544
workInProgress.stateNode,
@@ -592,7 +592,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
592
return bailoutOnAlreadyFinishedWork(current, workInProgress);
593
}
594
595
- if (!current) {
595
+ if (current === null) {
596
// Portals are special because we don't append the children during mount
597
// but at commit. Therefore we need to track insertions which the normal
598
// flow doesn't do during mount. This doesn't happen at the root because
@@ -632,7 +632,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
632
}
633
*/
634
635
- function bailoutOnAlreadyFinishedWork(current, workInProgress : Fiber) : ?Fiber {
635
+ function bailoutOnAlreadyFinishedWork(current, workInProgress : Fiber) : Fiber | null {
636
const priorityLevel = workInProgress.pendingWorkPriority;
637
// TODO: We should ideally be able to bail out early if the children have no
638
// more work to do. However, since we don't have a separation of this
@@ -687,7 +687,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
687
// is handled by beginUpdateQueue.
688
}
689
690
- function beginWork(current : ?Fiber, workInProgress : Fiber, priorityLevel : PriorityLevel) : ?Fiber {
690
+ function beginWork(current : Fiber | null, workInProgress : Fiber, priorityLevel : PriorityLevel) : Fiber | null {
691
if (workInProgress.pendingWorkPriority === NoWork ||
692
workInProgress.pendingWorkPriority > priorityLevel) {
693
return bailoutOnLowPriority(current, workInProgress);
@@ -744,7 +744,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
744
}
745
}
746
747
- function beginFailedWork(current : ?Fiber, workInProgress : Fiber, priorityLevel : PriorityLevel) {
747
+ function beginFailedWork(current : Fiber | null, workInProgress : Fiber, priorityLevel : PriorityLevel) {
748
invariant(
749
workInProgress.tag === ClassComponent ||
750
workInProgress.tag === HostRoot,
src/renderers/shared/fiber/ReactFiberClassComponent.js
+7
-7
@@ -71,7 +71,7 @@ module.exports = function(
71
};
72
73
function checkShouldComponentUpdate(workInProgress, oldProps, newProps, oldState, newState, newContext) {
74
- if (oldProps === null || (workInProgress.updateQueue && workInProgress.updateQueue.hasForceUpdate)) {
74
+ if (oldProps === null || (workInProgress.updateQueue !== null && workInProgress.updateQueue.hasForceUpdate)) {
75
// If the workInProgress already has an Update effect, return true
76
return true;
77
}
@@ -208,10 +208,10 @@ module.exports = function(
208
workInProgress.effectTag |= Update;
209
}
210
211
- function markUpdateIfAlreadyInProgress(current: ?Fiber, workInProgress : Fiber) {
211
+ function markUpdateIfAlreadyInProgress(current: Fiber | null, workInProgress : Fiber) {
212
// If an update was already in progress, we should schedule an Update
213
// effect even though we're bailing out, so that cWU/cDU are called.
214
- if (current) {
214
+ if (current !== null) {
215
if (workInProgress.memoizedProps !== current.memoizedProps ||
216
workInProgress.memoizedState !== current.memoizedState) {
217
markUpdate(workInProgress);
@@ -274,7 +274,7 @@ module.exports = function(
274
// If we had additional state updates during this life-cycle, let's
275
// process them now.
276
const updateQueue = workInProgress.updateQueue;
277
- if (updateQueue) {
277
+ if (updateQueue !== null) {
278
instance.state = beginUpdateQueue(
279
workInProgress,
280
updateQueue,
@@ -343,7 +343,7 @@ module.exports = function(
343
// They may be from componentWillMount() or from error boundary's setState()
344
// during initial mounting.
345
const newUpdateQueue = workInProgress.updateQueue;
346
- if (newUpdateQueue) {
346
+ if (newUpdateQueue !== null) {
347
newInstance.state = beginUpdateQueue(
348
workInProgress,
349
newUpdateQueue,
@@ -392,7 +392,7 @@ module.exports = function(
392
const oldState = workInProgress.memoizedState;
393
// TODO: Previous state can be null.
394
let newState;
395
- if (updateQueue) {
395
+ if (updateQueue !== null) {
396
newState = beginUpdateQueue(
397
workInProgress,
398
updateQueue,
@@ -408,7 +408,7 @@ module.exports = function(
408
if (oldProps === newProps &&
409
oldState === newState &&
410
!hasContextChanged() &&
411
- !(updateQueue && updateQueue.hasForceUpdate)) {
411
+ !(updateQueue !== null && updateQueue.hasForceUpdate)) {
412
markUpdateIfAlreadyInProgress(current, workInProgress);
413
return false;
414
}
src/renderers/shared/fiber/ReactFiberCommitWork.js
+29
-29
@@ -38,7 +38,7 @@ var invariant = require('invariant');
38
39
module.exports = function<T, P, I, TI, PI, C, CX, PL>(
40
config : HostConfig<T, P, I, TI, PI, C, CX, PL>,
41
- captureError : (failedFiber : Fiber, error: Error) => ?Fiber
41
+ captureError : (failedFiber : Fiber, error: Error) => Fiber | null
42
) {
43
44
const {
@@ -65,7 +65,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
65
function safelyDetachRef(current : Fiber) {
66
try {
67
const ref = current.ref;
68
- if (ref) {
68
+ if (ref !== null) {
69
ref(null);
70
}
71
} catch (error) {
@@ -74,10 +74,10 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
74
}
75
76
// Only called during update. It's ok to throw.
77
- function detachRefIfNeeded(current : ?Fiber, finishedWork : Fiber) {
77
+ function detachRefIfNeeded(current : Fiber | null, finishedWork : Fiber) {
78
if (current) {
79
const currentRef = current.ref;
80
- if (currentRef && currentRef !== finishedWork.ref) {
80
+ if (currentRef !== null && currentRef !== finishedWork.ref) {
81
currentRef(null);
82
}
83
}
@@ -85,7 +85,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
85
86
function getHostParent(fiber : Fiber) : I | C {
87
let parent = fiber.return;
88
- while (parent) {
88
+ while (parent !== null) {
89
switch (parent.tag) {
90
case HostComponent:
91
return parent.stateNode;
@@ -105,7 +105,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
105
106
function getHostParentFiber(fiber : Fiber) : Fiber {
107
let parent = fiber.return;
108
- while (parent) {
108
+ while (parent !== null) {
109
if (isHostParent(parent)) {
110
return parent;
111
}
@@ -134,8 +134,8 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
134
let node : Fiber = fiber;
135
siblings: while (true) {
136
// If we didn't find anything, let's try the next sibling.
137
- while (!node.sibling) {
138
- if (!node.return || isHostParent(node.return)) {
137
+ while (node.sibling === null) {
138
+ if (node.return === null || isHostParent(node.return)) {
139
// If we pop out of the root or hit the parent the fiber we are the
140
// last sibling.
141
return null;
@@ -153,7 +153,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
153
}
154
// If we don't have a child, try the siblings instead.
155
// We also skip portals because they are not part of this host tree.
156
- if (!node.child || node.tag === HostPortal) {
156
+ if (node.child === null || node.tag === HostPortal) {
157
continue siblings;
158
} else {
159
node.child.return = node;
@@ -211,7 +211,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
211
// If the insertion itself is a portal, then we don't want to traverse
212
// down its children. Instead, we'll get insertions from each child in
213
// the portal directly.
214
- } else if (node.child) {
214
+ } else if (node.child !== null) {
215
node.child.return = node;
216
node = node.child;
217
continue;
@@ -219,8 +219,8 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
219
if (node === finishedWork) {
220
return;
221
}
222
- while (!node.sibling) {
223
- if (!node.return || node.return === finishedWork) {
222
+ while (node.sibling === null) {
223
+ if (node.return === null || node.return === finishedWork) {
224
return;
225
}
226
node = node.return;
@@ -241,7 +241,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
241
commitUnmount(node);
242
// Visit children because they may contain more composite or host nodes.
243
// Skip portals because commitUnmount() currently visits them recursively.
244
- if (node.child && node.tag !== HostPortal) {
244
+ if (node.child !== null && node.tag !== HostPortal) {
245
node.child.return = node;
246
node = node.child;
247
continue;
@@ -249,8 +249,8 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
249
if (node === root) {
250
return;
251
}
252
- while (!node.sibling) {
253
- if (!node.return || node.return === root) {
252
+ while (node.sibling === null) {
253
+ if (node.return === null || node.return === root) {
254
return;
255
}
256
node = node.return;
@@ -276,7 +276,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
276
// We will reassign it back when we pop the portal on the way up.
277
parent = node.stateNode.containerInfo;
278
// Visit children because portals might contain host components.
279
- if (node.child) {
279
+ if (node.child !== null) {
280
node.child.return = node;
281
node = node.child;
282
continue;
@@ -284,7 +284,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
284
} else {
285
commitUnmount(node);
286
// Visit children because we may find more host components below.
287
- if (node.child) {
287
+ if (node.child !== null) {
288
node.child.return = node;
289
node = node.child;
290
continue;
@@ -293,8 +293,8 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
293
if (node === current) {
294
return;
295
}
296
- while (!node.sibling) {
297
- if (!node.return || node.return === current) {
296
+ while (node.sibling === null) {
297
+ if (node.return === null || node.return === current) {
298
return;
299
}
300
node = node.return;
@@ -364,7 +364,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
364
}
365
}
366
367
- function commitWork(current : ?Fiber, finishedWork : Fiber) : void {
367
+ function commitWork(current : Fiber | null, finishedWork : Fiber) : void {
368
switch (finishedWork.tag) {
369
case ClassComponent: {
370
detachRefIfNeeded(current, finishedWork);
@@ -372,7 +372,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
372
}
373
case HostComponent: {
374
const instance : I = finishedWork.stateNode;
375
- if (instance != null && current) {
375
+ if (instance != null && current !== null) {
376
// Commit the work prepared earlier.
377
const newProps = finishedWork.memoizedProps;
378
const oldProps = current.memoizedProps;
@@ -380,7 +380,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
380
// TODO: Type the updateQueue to be specific to host components.
381
const updatePayload : null | PL = (finishedWork.updateQueue : any);
382
finishedWork.updateQueue = null;
383
- if (updatePayload) {
383
+ if (updatePayload !== null) {
384
commitUpdate(instance, updatePayload, type, oldProps, newProps, finishedWork);
385
}
386
}
@@ -389,7 +389,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
389
}
390
case HostText: {
391
invariant(
392
- finishedWork.stateNode !== null && current != null,
392
+ finishedWork.stateNode !== null && current !== null,
393
'This should only be done during updates. This error is likely ' +
394
'caused by a bug in React. Please file an issue.'
395
);
@@ -415,12 +415,12 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
415
}
416
}
417
418
- function commitLifeCycles(current : ?Fiber, finishedWork : Fiber) : void {
418
+ function commitLifeCycles(current : Fiber | null, finishedWork : Fiber) : void {
419
switch (finishedWork.tag) {
420
case ClassComponent: {
421
const instance = finishedWork.stateNode;
422
if (finishedWork.effectTag & Update) {
423
- if (!current) {
423
+ if (current === null) {
424
if (typeof instance.componentDidMount === 'function') {
425
instance.componentDidMount();
426
}
@@ -432,14 +432,14 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
432
}
433
}
434
}
435
- if ((finishedWork.effectTag & Callback) && finishedWork.updateQueue) {
435
+ if ((finishedWork.effectTag & Callback) && finishedWork.updateQueue !== null) {
436
commitCallbacks(finishedWork, finishedWork.updateQueue, instance);
437
}
438
return;
439
}
440
case HostRoot: {
441
const updateQueue = finishedWork.updateQueue;
442
- if (updateQueue) {
442
+ if (updateQueue !== null) {
443
const instance = finishedWork.child && finishedWork.child.stateNode;
444
commitCallbacks(finishedWork, updateQueue, instance);
445
}
@@ -453,7 +453,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
453
// These effects should only be committed when components are first mounted,
454
// aka when there is no current/alternate.
455
if (
456
- !current &&
456
+ current === null &&
457
finishedWork.effectTag & Update
458
) {
459
const type = finishedWork.type;
@@ -486,7 +486,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
486
return;
487
}
488
const ref = finishedWork.ref;
489
- if (ref) {
489
+ if (ref !== null) {
490
const instance = getPublicInstance(finishedWork.stateNode);
491
ref(instance);
492
}
src/renderers/shared/fiber/ReactFiberCompleteWork.js
+14
-14
@@ -71,7 +71,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
71
// We now have clones. Let's store them as the currently progressed work.
72
workInProgress.progressedChild = workInProgress.child;
73
workInProgress.progressedPriority = priorityLevel;
74
- if (current) {
74
+ if (current !== null) {
75
// We also store it on the current. When the alternate swaps in we can
76
// continue from this point.
77
current.progressedChild = workInProgress.progressedChild;
@@ -90,7 +90,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
90
if (node) {
91
node.return = workInProgress;
92
}
93
- while (node) {
93
+ while (node !== null) {
94
if (node.tag === HostComponent || node.tag === HostText ||
95
node.tag === HostPortal) {
96
invariant(
@@ -99,13 +99,13 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
99
);
100
} else if (node.tag === YieldComponent) {
101
yields.push(node.type);
102
- } else if (node.child) {
102
+ } else if (node.child !== null) {
103
node.child.return = node;
104
node = node.child;
105
continue;
106
}
107
- while (!node.sibling) {
108
- if (!node.return || node.return === workInProgress) {
107
+ while (node.sibling === null) {
108
+ if (node.return === null || node.return === workInProgress) {
109
return;
110
}
111
node = node.return;
@@ -115,7 +115,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
115
}
116
}
117
118
- function moveCoroutineToHandlerPhase(current : ?Fiber, workInProgress : Fiber) {
118
+ function moveCoroutineToHandlerPhase(current : Fiber | null, workInProgress : Fiber) {
119
var coroutine = (workInProgress.memoizedProps : ?ReactCoroutine);
120
invariant(
121
coroutine,
@@ -140,7 +140,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
140
var props = coroutine.props;
141
var nextChildren = fn(props, yields);
142
143
- var currentFirstChild = current ? current.child : null;
143
+ var currentFirstChild = current !== null ? current.child : null;
144
// Inherit the priority of the returnFiber.
145
const priority = workInProgress.pendingWorkPriority;
146
workInProgress.child = reconcileChildFibers(
@@ -157,22 +157,22 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
157
// We only have the top Fiber that was created but we need recurse down its
158
// children to find all the terminal nodes.
159
let node = workInProgress.child;
160
- while (node) {
160
+ while (node !== null) {
161
if (node.tag === HostComponent || node.tag === HostText) {
162
appendInitialChild(parent, node.stateNode);
163
} else if (node.tag === HostPortal) {
164
// If we have a portal child, then we don't want to traverse
165
// down its children. Instead, we'll get insertions from each child in
166
// the portal directly.
167
- } else if (node.child) {
167
+ } else if (node.child !== null) {
168
node = node.child;
169
continue;
170
}
171
if (node === workInProgress) {
172
return;
173
}
174
- while (!node.sibling) {
175
- if (!node.return || node.return === workInProgress) {
174
+ while (node.sibling === null) {
175
+ if (node.return === null || node.return === workInProgress) {
176
return;
177
}
178
node = node.return;
@@ -181,7 +181,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
181
}
182
}
183
184
- function completeWork(current : ?Fiber, workInProgress : Fiber) : ?Fiber {
184
+ function completeWork(current : Fiber | null, workInProgress : Fiber) : Fiber | null {
185
if (__DEV__) {
186
ReactDebugCurrentFiber.current = workInProgress;
187
}
@@ -208,7 +208,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
208
const rootContainerInstance = getRootHostContainer();
209
const type = workInProgress.type;
210
const newProps = workInProgress.memoizedProps;
211
- if (current && workInProgress.stateNode != null) {
211
+ if (current !== null && workInProgress.stateNode != null) {
212
// If we have an alternate, that means this is an update and we need to
213
// schedule a side-effect to do the updates.
214
const oldProps = current.memoizedProps;
@@ -268,7 +268,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
268
}
269
270
workInProgress.stateNode = instance;
271
- if (workInProgress.ref) {
271
+ if (workInProgress.ref !== null) {
272
// If there is a ref on a host node we need to schedule a callback
273
workInProgress.effectTag |= Ref;
274
}
src/renderers/shared/fiber/ReactFiberContext.js
+1
-1
@@ -149,7 +149,7 @@ function processChildContext(fiber : Fiber, parentContext : Object, isReconcilin
149
if (typeof instance.getChildContext !== 'function') {
150
if (__DEV__) {
151
const componentName = getComponentName(fiber);
152
-
152
+
153
if (!warnedAboutMissingGetChildContext[componentName]) {
154
warnedAboutMissingGetChildContext[componentName] = true;
155
warning(
src/renderers/shared/fiber/ReactFiberHostContext.js
+7
-5
@@ -44,14 +44,14 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
44
getRootHostContext,
45
} = config;
46
47
- let contextStackCursor : StackCursor<?CX> = createCursor((null: ?CX));
48
- let contextFiberStackCursor : StackCursor<?Fiber> = createCursor((null: ?Fiber));
49
- let rootInstanceStackCursor : StackCursor<?C> = createCursor((null: ?C));
47
+ let contextStackCursor : StackCursor<CX | null> = createCursor((null: ?CX));
48
+ let contextFiberStackCursor : StackCursor<Fiber | null> = createCursor((null: Fiber | null));
49
+ let rootInstanceStackCursor : StackCursor<C | null> = createCursor((null: ?C));
50
51
function getRootHostContainer() : C {
52
const rootInstance = rootInstanceStackCursor.current;
53
invariant(
54
- rootInstance != null,
54
+ rootInstance !== null,
55
'Expected root container to exist. This error is likely caused by a ' +
56
'bug in React. Please file an issue.'
57
);
@@ -95,7 +95,9 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
95
'a bug in React. Please file an issue.'
96
);
97
98
- const context = contextStackCursor.current || emptyObject;
98
+ const context = contextStackCursor.current !== null ?
99
+ contextStackCursor.current :
100
+ emptyObject;
101
const nextContext = getChildHostContext(context, fiber.type, rootInstance);
102
103
// Don't push this Fiber's context unless it's unique.
src/renderers/shared/fiber/ReactFiberReconciler.js
+1
-1
@@ -206,7 +206,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
206
207
findHostInstance(fiber : Fiber) : I | TI | null {
208
const hostFiber = findCurrentHostFiber(fiber);
209
- if (!hostFiber) {
209
+ if (hostFiber === null) {
210
return null;
211
}
212
return hostFiber.stateNode;
src/renderers/shared/fiber/ReactFiberRoot.js
+3
-3
@@ -24,10 +24,10 @@ export type FiberRoot = {
24
// Determines if this root has already been added to the schedule for work.
25
isScheduled: boolean,
26
// The work schedule is a linked list.
27
- nextScheduledRoot: ?FiberRoot,
27
+ nextScheduledRoot: FiberRoot | null,
28
// Top context object, used by renderSubtreeIntoContainer
29
- context: ?Object,
30
- pendingContext: ?Object,
29
+ context: Object | null,
30
+ pendingContext: Object | null,
31
};
32
33
exports.createFiberRoot = function(containerInfo : any) : FiberRoot {
src/renderers/shared/fiber/ReactFiberScheduler.js
+84
-90
@@ -22,7 +22,7 @@ export type CapturedError = {
22
componentStack : string,
23
error : Error,
24
errorBoundaryFound : boolean,
25
- errorBoundaryName : ?string,
25
+ errorBoundaryName : string | null,
26
willRetry : boolean,
27
};
28
@@ -134,17 +134,17 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
134
let isBatchingUpdates : boolean = false;
135
136
// The next work in progress fiber that we're currently working on.
137
- let nextUnitOfWork : ?Fiber = null;
137
+ let nextUnitOfWork : Fiber | null = null;
138
let nextPriorityLevel : PriorityLevel = NoWork;
139
140
// The next fiber with an effect that we're currently committing.
141
- let nextEffect : ?Fiber = null;
141
+ let nextEffect : Fiber | null = null;
142
143
- let pendingCommit : ?Fiber = null;
143
+ let pendingCommit : Fiber | null = null;
144
145
// Linked list of roots with scheduled work on them.
146
- let nextScheduledRoot : ?FiberRoot = null;
147
- let lastScheduledRoot : ?FiberRoot = null;
146
+ let nextScheduledRoot : FiberRoot | null = null;
147
+ let lastScheduledRoot : FiberRoot | null = null;
148
149
// Keep track of which host environment callbacks are scheduled.
150
let isAnimationCallbackScheduled : boolean = false;
@@ -193,7 +193,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
193
// the work loop.
194
function findNextUnitOfWork() {
195
// Clear out roots with no more work on them, or if they have uncaught errors
196
- while (nextScheduledRoot && nextScheduledRoot.current.pendingWorkPriority === NoWork) {
196
+ while (nextScheduledRoot !== null && nextScheduledRoot.current.pendingWorkPriority === NoWork) {
197
// Unschedule this root.
198
nextScheduledRoot.isScheduled = false;
199
// Read the next pointer now.
@@ -215,7 +215,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
215
let root = nextScheduledRoot;
216
let highestPriorityRoot = null;
217
let highestPriorityLevel = NoWork;
218
- while (root) {
218
+ while (root !== null) {
219
if (root.current.pendingWorkPriority !== NoWork && (
220
highestPriorityLevel === NoWork ||
221
highestPriorityLevel > root.current.pendingWorkPriority)) {
@@ -225,7 +225,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
225
// We didn't find anything to do in this root, so let's try the next one.
226
root = root.nextScheduledRoot;
227
}
228
- if (highestPriorityRoot) {
228
+ if (highestPriorityRoot !== null) {
229
nextPriorityLevel = highestPriorityLevel;
230
priorityContext = nextPriorityLevel;
231
@@ -247,7 +247,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
247
}
248
249
function commitAllHostEffects() {
250
- while (nextEffect) {
250
+ while (nextEffect !== null) {
251
if (__DEV__) {
252
ReactDebugCurrentFiber.current = nextEffect;
253
}
@@ -306,7 +306,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
306
}
307
308
function commitAllLifeCycles() {
309
- while (nextEffect) {
309
+ while (nextEffect !== null) {
310
const current = nextEffect.alternate;
311
// Use Task priority for lifecycle updates
312
if (nextEffect.effectTag & (Update | Callback)) {
@@ -359,7 +359,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
359
// the root has an effect, we need to add it to the end of the list. The
360
// resulting list is the set that would belong to the root's parent, if
361
// it had one; that is, all the effects in the tree including the root.
362
- if (finishedWork.lastEffect) {
362
+ if (finishedWork.lastEffect !== null) {
363
finishedWork.lastEffect.nextEffect = finishedWork;
364
firstEffect = finishedWork.firstEffect;
365
} else {
@@ -376,18 +376,18 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
376
// The first pass performs all the host insertions, updates, deletions and
377
// ref unmounts.
378
nextEffect = firstEffect;
379
- while (nextEffect) {
379
+ while (nextEffect !== null) {
380
try {
381
commitAllHostEffects(finishedWork);
382
} catch (error) {
383
invariant(
384
- nextEffect != null,
384
+ nextEffect !== null,
385
'Should have next effect. This error is likely caused by a bug ' +
386
'in React. Please file an issue.'
387
);
388
captureError(nextEffect, error);
389
// Clean-up
390
- if (nextEffect) {
390
+ if (nextEffect !== null) {
391
nextEffect = nextEffect.nextEffect;
392
}
393
}
@@ -406,17 +406,17 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
406
// and deletions in the entire tree have already been invoked.
407
// This pass also triggers any renderer-specific initial effects.
408
nextEffect = firstEffect;
409
- while (nextEffect) {
409
+ while (nextEffect !== null) {
410
try {
411
commitAllLifeCycles(finishedWork, nextEffect);
412
} catch (error) {
413
invariant(
414
- nextEffect != null,
414
+ nextEffect !== null,
415
'Should have next effect. This error is likely caused by a bug ' +
416
'in React. Please file an issue.'
417
);
418
captureError(nextEffect, error);
419
- if (nextEffect) {
419
+ if (nextEffect !== null) {
420
nextEffect = nextEffect.nextEffect;
421
}
422
}
@@ -446,7 +446,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
446
// Check for pending update priority. This is usually null so it shouldn't
447
// be a perf issue.
448
const queue = workInProgress.updateQueue;
449
- if (queue) {
449
+ if (queue !== null) {
450
newPriority = getPendingPriority(queue);
451
}
452
@@ -456,7 +456,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
456
// Either it is the same as child, or it just bailed out because it choose
457
// not to do the work.
458
let child = workInProgress.progressedChild;
459
- while (child) {
459
+ while (child !== null) {
460
// Ensure that remaining work priority bubbles up.
461
if (child.pendingWorkPriority !== NoWork &&
462
(newPriority === NoWork ||
@@ -468,7 +468,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
468
workInProgress.pendingWorkPriority = newPriority;
469
}
470
471
- function completeUnitOfWork(workInProgress : Fiber) : ?Fiber {
471
+ function completeUnitOfWork(workInProgress : Fiber) : Fiber | null {
472
while (true) {
473
// The current, flushed, state of this fiber is the alternate.
474
// Ideally nothing should rely on this, but relying on it here
@@ -482,7 +482,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
482
483
resetWorkPriority(workInProgress);
484
485
- if (next) {
485
+ if (next !== null) {
486
if (__DEV__ && ReactFiberInstrumentation.debugTool) {
487
ReactFiberInstrumentation.debugTool.onCompleteWork(workInProgress);
488
}
@@ -491,15 +491,15 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
491
return next;
492
}
493
494
- if (returnFiber) {
494
+ if (returnFiber !== null) {
495
// Append all the effects of the subtree and this fiber onto the effect
496
// list of the parent. The completion order of the children affects the
497
// side-effect order.
498
- if (!returnFiber.firstEffect) {
498
+ if (returnFiber.firstEffect === null) {
499
returnFiber.firstEffect = workInProgress.firstEffect;
500
}
501
- if (workInProgress.lastEffect) {
502
- if (returnFiber.lastEffect) {
501
+ if (workInProgress.lastEffect !== null) {
502
+ if (returnFiber.lastEffect !== null) {
503
returnFiber.lastEffect.nextEffect = workInProgress.firstEffect;
504
}
505
returnFiber.lastEffect = workInProgress.lastEffect;
@@ -512,7 +512,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
512
// reusing children we'll schedule this effect onto itself since we're
513
// at the end.
514
if (workInProgress.effectTag !== NoEffect) {
515
- if (returnFiber.lastEffect) {
515
+ if (returnFiber.lastEffect !== null) {
516
returnFiber.lastEffect.nextEffect = workInProgress;
517
} else {
518
returnFiber.firstEffect = workInProgress;
@@ -525,10 +525,10 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
525
ReactFiberInstrumentation.debugTool.onCompleteWork(workInProgress);
526
}
527
528
- if (siblingFiber) {
528
+ if (siblingFiber !== null) {
529
// If there is more work to do in this returnFiber, do that next.
530
return siblingFiber;
531
- } else if (returnFiber) {
531
+ } else if (returnFiber !== null) {
532
// If there's no more work in this returnFiber. Complete the returnFiber.
533
workInProgress = returnFiber;
534
continue;
@@ -548,7 +548,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
548
}
549
}
550
551
- function performUnitOfWork(workInProgress : Fiber) : ?Fiber {
551
+ function performUnitOfWork(workInProgress : Fiber) : Fiber | null {
552
// The current, flushed, state of this fiber is the alternate.
553
// Ideally nothing should rely on this, but relying on it here
554
// means that we don't need an additional field on the work in
@@ -561,7 +561,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
561
ReactFiberInstrumentation.debugTool.onBeginWork(workInProgress);
562
}
563
564
- if (!next) {
564
+ if (next === null) {
565
// If this doesn't spawn new work, complete the current work.
566
next = completeUnitOfWork(workInProgress);
567
}
@@ -574,7 +574,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
574
return next;
575
}
576
577
- function performFailedUnitOfWork(workInProgress : Fiber) : ?Fiber {
577
+ function performFailedUnitOfWork(workInProgress : Fiber) : Fiber | null {
578
579
// The current, flushed, state of this fiber is the alternate.
580
// Ideally nothing should rely on this, but relying on it here
@@ -588,7 +588,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
588
ReactFiberInstrumentation.debugTool.onBeginWork(workInProgress);
589
}
590
591
- if (!next) {
591
+ if (next === null) {
592
// If this doesn't spawn new work, complete the current work.
593
next = completeUnitOfWork(workInProgress);
594
}
@@ -610,16 +610,16 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
610
611
function performAnimationWork() {
612
isAnimationCallbackScheduled = false;
613
- performWork(AnimationPriority);
613
+ performWork(AnimationPriority, null);
614
}
615
616
function clearErrors() {
617
- if (!nextUnitOfWork) {
617
+ if (nextUnitOfWork === null) {
618
nextUnitOfWork = findNextUnitOfWork();
619
}
620
// Keep performing work until there are no more errors
621
- while (capturedErrors && capturedErrors.size &&
622
- nextUnitOfWork &&
621
+ while (capturedErrors !== null && capturedErrors.size &&
622
+ nextUnitOfWork !== null &&
623
nextPriorityLevel !== NoWork &&
624
nextPriorityLevel <= TaskPriority) {
625
if (hasCapturedError(nextUnitOfWork)) {
@@ -628,7 +628,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
628
} else {
629
nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
630
}
631
- if (!nextUnitOfWork) {
631
+ if (nextUnitOfWork === null) {
632
// If performUnitOfWork returns null, that means we just comitted
633
// a root. Normally we'd need to clear any errors that were scheduled
634
// during the commit phase. But we're already clearing errors, so
@@ -642,16 +642,16 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
642
// Clear any errors.
643
clearErrors();
644
645
- if (!nextUnitOfWork) {
645
+ if (nextUnitOfWork === null) {
646
nextUnitOfWork = findNextUnitOfWork();
647
}
648
649
let hostRootTimeMarker;
650
if (
651
ReactFeatureFlags.logTopLevelRenders &&
652
- nextUnitOfWork &&
652
+ nextUnitOfWork !== null &&
653
nextUnitOfWork.tag === HostRoot &&
654
- nextUnitOfWork.child
654
+ nextUnitOfWork.child !== null
655
) {
656
const componentName = getComponentName(nextUnitOfWork.child) || '';
657
hostRootTimeMarker = 'React update: ' + componentName;
@@ -660,17 +660,17 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
660
661
// If there's a deadline, and we're not performing Task work, perform work
662
// using this loop that checks the deadline on every iteration.
663
- if (deadline && priorityLevel > TaskPriority) {
663
+ if (deadline !== null && priorityLevel > TaskPriority) {
664
// The deferred work loop will run until there's no time left in
665
// the current frame.
666
- while (nextUnitOfWork && !deadlineHasExpired) {
666
+ while (nextUnitOfWork !== null && !deadlineHasExpired) {
667
if (deadline.timeRemaining() > timeHeuristicForUnitOfWork) {
668
nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
669
// In a deferred work batch, iff nextUnitOfWork returns null, we just
670
// completed a root and a pendingCommit exists. Logically, we could
671
// omit either of the checks in the following condition, but we need
672
// both to satisfy Flow.
673
- if (!nextUnitOfWork && pendingCommit) {
673
+ if (nextUnitOfWork === null && pendingCommit !== null) {
674
// If we have time, we should commit the work now.
675
if (deadline.timeRemaining() > timeHeuristicForUnitOfWork) {
676
commitAllWork(pendingCommit);
@@ -690,11 +690,11 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
690
// If there's no deadline, or if we're performing Task work, use this loop
691
// that doesn't check how much time is remaining. It will keep running
692
// until we run out of work at this priority level.
693
- while (nextUnitOfWork &&
693
+ while (nextUnitOfWork !== null &&
694
nextPriorityLevel !== NoWork &&
695
nextPriorityLevel <= priorityLevel) {
696
nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
697
- if (!nextUnitOfWork) {
697
+ if (nextUnitOfWork === null) {
698
nextUnitOfWork = findNextUnitOfWork();
699
// performUnitOfWork returned null, which means we just comitted a
700
// root. Clear any errors that were scheduled during the commit phase.
@@ -725,14 +725,14 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
725
// deferred batch.
726
while (priorityLevel !== NoWork && !fatalError) {
727
invariant(
728
- deadline || (priorityLevel < HighPriority),
728
+ deadline !== null || (priorityLevel < HighPriority),
729
'Cannot perform deferred work without a deadline. This error is ' +
730
'likely caused by a bug in React. Please file an issue.'
731
);
732
733
// Before starting any work, check to see if there are any pending
734
// commits from the previous frame.
735
- if (pendingCommit && !deadlineHasExpired) {
735
+ if (pendingCommit !== null && !deadlineHasExpired) {
736
commitAllWork(pendingCommit);
737
}
738
@@ -746,7 +746,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
746
} catch (error) {
747
// We caught an error during either the begin or complete phases.
748
const failedWork = nextUnitOfWork;
749
- if (failedWork) {
749
+ if (failedWork !== null) {
750
// Reset the priority context to its value before reconcilation.
751
priorityContext = priorityContextBeforeReconciliation;
752
@@ -754,7 +754,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
754
// error boundary, the nearest host container acts as one. If
755
// captureError returns null, the error was intentionally ignored.
756
const maybeBoundary = captureError(failedWork, error);
757
- if (maybeBoundary) {
757
+ if (maybeBoundary !== null) {
758
const boundary = maybeBoundary;
759
760
// Complete the boundary as if it rendered null. This will unmount
@@ -774,7 +774,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
774
}
775
// Continue performing work
776
continue;
777
- } else if (!fatalError) {
777
+ } else if (fatalError === null) {
778
// There is no current unit of work. This is a worst-case scenario
779
// and should only be possible if there's a bug in the renderer, e.g.
780
// inside resetAfterCommit.
@@ -830,13 +830,13 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
830
failedBoundaries = null;
831
832
// It's safe to throw any unhandled errors.
833
- if (errorToThrow) {
833
+ if (errorToThrow !== null) {
834
throw errorToThrow;
835
}
836
}
837
838
// Returns the boundary that captured the error, or null if the error is ignored
839
- function captureError(failedWork : Fiber, error : Error) : ?Fiber {
839
+ function captureError(failedWork : Fiber, error : Error) : Fiber | null {
840
// It is no longer valid because we exited the user code.
841
ReactCurrentOwner.current = null;
842
if (__DEV__) {
@@ -846,12 +846,12 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
846
nextUnitOfWork = null;
847
848
// Search for the nearest error boundary.
849
- let boundary : ?Fiber = null;
849
+ let boundary : Fiber | null = null;
850
851
// Passed to logCapturedError()
852
let errorBoundaryFound : boolean = false;
853
let willRetry : boolean = false;
854
- let errorBoundaryName : ?string = null;
854
+ let errorBoundaryName : string | null = null;
855
856
// Host containers are a special case. If the failed work itself is a host
857
// container, then it acts as its own boundary. In all other cases, we
@@ -867,7 +867,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
867
}
868
} else {
869
let node = failedWork.return;
870
- while (node && !boundary) {
870
+ while (node !== null && boundary === null) {
871
if (node.tag === ClassComponent) {
872
const instance = node.stateNode;
873
if (typeof instance.unstable_handleError === 'function') {
@@ -897,9 +897,9 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
897
// this boundary already captured an error during this commit.
898
// This case exists because multiple errors can be thrown during
899
// a single commit without interruption.
900
- if (commitPhaseBoundaries && (
900
+ if (commitPhaseBoundaries !== null && (
901
commitPhaseBoundaries.has(node) ||
902
- (node.alternate) && commitPhaseBoundaries.has(node.alternate)
902
+ (node.alternate !== null && commitPhaseBoundaries.has(node.alternate))
903
)) {
904
// If so, we should ignore this error.
905
return null;
@@ -914,10 +914,10 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
914
}
915
}
916
917
- if (boundary) {
917
+ if (boundary !== null) {
918
// Add to the collection of failed boundaries. This lets us know that
919
// subsequent errors in this subtree should propagate to the next boundary.
920
- if (!failedBoundaries) {
920
+ if (failedBoundaries === null) {
921
failedBoundaries = new Set();
922
}
923
failedBoundaries.add(boundary);
@@ -933,7 +933,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
933
// map of errors and their component stack location keyed by the boundaries
934
// that capture them. We mostly use this Map as a Set; it's a Map only to
935
// avoid adding a field to Fiber to store the error.
936
- if (!capturedErrors) {
936
+ if (capturedErrors === null) {
937
capturedErrors = new Map();
938
}
939
capturedErrors.set(boundary, {
@@ -948,7 +948,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
948
// If we're in the commit phase, defer scheduling an update on the
949
// boundary until after the commit is complete
950
if (isCommitting) {
951
- if (!commitPhaseBoundaries) {
951
+ if (commitPhaseBoundaries === null) {
952
commitPhaseBoundaries = new Set();
953
}
954
commitPhaseBoundaries.add(boundary);
@@ -957,7 +957,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
957
scheduleErrorRecovery(boundary);
958
}
959
return boundary;
960
- } else if (!firstUncaughtError) {
960
+ } else if (firstUncaughtError === null) {
961
// If no boundary is found, we'll need to throw the error
962
firstUncaughtError = error;
963
}
@@ -968,8 +968,8 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
968
// TODO: capturedErrors should store the boundary instance, to avoid needing
969
// to check the alternate.
970
return Boolean(
971
- capturedErrors &&
972
- (capturedErrors.has(fiber) || (fiber.alternate && capturedErrors.has(fiber.alternate)))
971
+ capturedErrors !== null &&
972
+ (capturedErrors.has(fiber) || (fiber.alternate !== null && capturedErrors.has(fiber.alternate)))
973
);
974
}
975
@@ -977,18 +977,18 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
977
// TODO: failedBoundaries should store the boundary instance, to avoid
978
// needing to check the alternate.
979
return Boolean(
980
- failedBoundaries &&
981
- (failedBoundaries.has(fiber) || (fiber.alternate && failedBoundaries.has(fiber.alternate)))
980
+ failedBoundaries !== null &&
981
+ (failedBoundaries.has(fiber) || (fiber.alternate !== null && failedBoundaries.has(fiber.alternate)))
982
);
983
}
984
985
function commitErrorHandling(effectfulFiber : Fiber) {
986
let capturedError;
987
- if (capturedErrors) {
987
+ if (capturedErrors !== null) {
988
capturedError = capturedErrors.get(effectfulFiber);
989
capturedErrors.delete(effectfulFiber);
990
- if (!capturedError) {
991
- if (effectfulFiber.alternate) {
990
+ if (capturedError == null) {
991
+ if (effectfulFiber.alternate !== null) {
992
effectfulFiber = effectfulFiber.alternate;
993
capturedError = capturedErrors.get(effectfulFiber);
994
capturedErrors.delete(effectfulFiber);
@@ -1002,19 +1002,13 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
1002
'bug in React. Please file an issue.'
1003
);
1004
1005
- let error;
1006
-
1007
- // Conditional required to satisfy Flow
1008
- if (capturedError) {
1009
- error = capturedError.error;
1010
-
1011
- try {
1012
- logCapturedError(capturedError);
1013
- } catch (e) {
1014
- // Prevent cycle if logCapturedError() throws.
1015
- // A cycle may still occur if logCapturedError renders a component that throws.
1016
- console.error(e);
1017
- }
1005
+ const error = capturedError.error;
1006
+ try {
1007
+ logCapturedError(capturedError);
1008
+ } catch (e) {
1009
+ // Prevent cycle if logCapturedError() throws.
1010
+ // A cycle may still occur if logCapturedError renders a component that throws.
1011
+ console.error(e);
1012
}
1013
1014
switch (effectfulFiber.tag) {
@@ -1025,7 +1019,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
1019
instance.unstable_handleError(error);
1020
return;
1021
case HostRoot:
1028
- if (!firstUncaughtError) {
1022
+ if (firstUncaughtError === null) {
1023
// If this is the host container, we treat it as a no-op error
1024
// boundary. We'll throw the first uncaught error once it's safe to
1025
// do so, at the end of the batch.
@@ -1043,7 +1037,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
1037
1038
function unwindContexts(from : Fiber, to: Fiber) {
1039
let node = from;
1046
- while (node && (node !== to) && (node.alternate !== to)) {
1040
+ while (node !== null && (node !== to) && (node.alternate !== to)) {
1041
switch (node.tag) {
1042
case ClassComponent:
1043
popContextProvider(node);
@@ -1091,7 +1085,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
1085
1086
let node = fiber;
1087
let shouldContinue = true;
1094
- while (node && shouldContinue) {
1088
+ while (node !== null && shouldContinue) {
1089
// Walk the parent path to the root and update each node's priority. Once
1090
// we reach a node whose priority matches (and whose alternate's priority
1091
// matches) we can exit safely knowing that the rest of the path is correct.
@@ -1102,7 +1096,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
1096
shouldContinue = true;
1097
node.pendingWorkPriority = priorityLevel;
1098
}
1105
- if (node.alternate) {
1099
+ if (node.alternate !== null) {
1100
if (node.alternate.pendingWorkPriority === NoWork ||
1101
node.alternate.pendingWorkPriority > priorityLevel) {
1102
// Priority did not match. Update and keep going.
@@ -1110,7 +1104,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
1104
node.alternate.pendingWorkPriority = priorityLevel;
1105
}
1106
}
1113
- if (!node.return) {
1107
+ if (node.return === null) {
1108
if (node.tag === HostRoot) {
1109
const root : FiberRoot = (node.stateNode : any);
1110
scheduleRoot(root, priorityLevel);
@@ -1118,7 +1112,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
1112
// schedule a callback to perform work later.
1113
switch (priorityLevel) {
1114
case SynchronousPriority:
1121
- performWork(SynchronousPriority);
1115
+ performWork(SynchronousPriority, null);
1116
return;
1117
case TaskPriority:
1118
// TODO: If we're not already performing work, schedule a
@@ -1175,7 +1169,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(config : HostConfig<T, P,
1169
// If we're not already inside a batch, we need to flush any task work
1170
// that was created by the user-provided function.
1171
if (!isPerformingWork && !isBatchingUpdates) {
1178
- performWork(TaskPriority);
1172
+ performWork(TaskPriority, null);
1173
}
1174
}
1175
}