react-dom 16.8.1 → 16.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build-info.json +6 -6
- package/cjs/react-dom-server.browser.development.js +55 -34
- package/cjs/react-dom-server.browser.production.min.js +3 -3
- package/cjs/react-dom-server.node.development.js +55 -34
- package/cjs/react-dom-server.node.production.min.js +3 -3
- package/cjs/react-dom-test-utils.development.js +2 -2
- package/cjs/react-dom-test-utils.production.min.js +1 -1
- package/cjs/react-dom-unstable-fire.development.js +464 -139
- package/cjs/react-dom-unstable-fire.production.min.js +252 -251
- package/cjs/react-dom-unstable-fire.profiling.min.js +175 -173
- package/cjs/react-dom-unstable-fizz.browser.development.js +1 -1
- package/cjs/react-dom-unstable-fizz.browser.production.min.js +1 -1
- package/cjs/react-dom-unstable-fizz.node.development.js +1 -1
- package/cjs/react-dom-unstable-fizz.node.production.min.js +1 -1
- package/cjs/react-dom-unstable-native-dependencies.development.js +2 -2
- package/cjs/react-dom-unstable-native-dependencies.production.min.js +1 -1
- package/cjs/react-dom.development.js +464 -139
- package/cjs/react-dom.production.min.js +252 -251
- package/cjs/react-dom.profiling.min.js +175 -173
- package/package.json +2 -2
- package/umd/react-dom-server.browser.development.js +55 -34
- package/umd/react-dom-server.browser.production.min.js +20 -20
- package/umd/react-dom-test-utils.development.js +2 -2
- package/umd/react-dom-test-utils.production.min.js +1 -1
- package/umd/react-dom-unstable-fire.development.js +472 -139
- package/umd/react-dom-unstable-fire.production.min.js +208 -207
- package/umd/react-dom-unstable-fire.profiling.min.js +208 -208
- package/umd/react-dom-unstable-fizz.browser.development.js +1 -1
- package/umd/react-dom-unstable-fizz.browser.production.min.js +1 -1
- package/umd/react-dom-unstable-native-dependencies.development.js +2 -2
- package/umd/react-dom-unstable-native-dependencies.production.min.js +1 -1
- package/umd/react-dom.development.js +472 -139
- package/umd/react-dom.production.min.js +208 -207
- package/umd/react-dom.profiling.min.js +208 -208
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @license React v16.8.
|
|
1
|
+
/** @license React v16.8.2
|
|
2
2
|
* react-dom.development.js
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
@@ -85,7 +85,7 @@ var invokeGuardedCallbackImpl = function (name, func, context, a, b, c, d, e, f)
|
|
|
85
85
|
// invokeGuardedCallback uses a try-catch, all user exceptions are treated
|
|
86
86
|
// like caught exceptions, and the DevTools won't pause unless the developer
|
|
87
87
|
// takes the extra step of enabling pause on caught exceptions. This is
|
|
88
|
-
//
|
|
88
|
+
// unintuitive, though, because even though React has caught the error, from
|
|
89
89
|
// the developer's perspective, the error is uncaught.
|
|
90
90
|
//
|
|
91
91
|
// To preserve the expected "Pause on exceptions" behavior, we don't use a
|
|
@@ -842,6 +842,7 @@ var MemoComponent = 14;
|
|
|
842
842
|
var SimpleMemoComponent = 15;
|
|
843
843
|
var LazyComponent = 16;
|
|
844
844
|
var IncompleteClassComponent = 17;
|
|
845
|
+
var DehydratedSuspenseComponent = 18;
|
|
845
846
|
|
|
846
847
|
var randomKey = Math.random().toString(36).slice(2);
|
|
847
848
|
var internalInstanceKey = '__reactInternalInstance$' + randomKey;
|
|
@@ -2903,12 +2904,15 @@ var capitalize = function (token) {
|
|
|
2903
2904
|
attributeName, 'http://www.w3.org/XML/1998/namespace');
|
|
2904
2905
|
});
|
|
2905
2906
|
|
|
2906
|
-
//
|
|
2907
|
-
//
|
|
2908
|
-
//
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
2907
|
+
// These attribute exists both in HTML and SVG.
|
|
2908
|
+
// The attribute name is case-sensitive in SVG so we can't just use
|
|
2909
|
+
// the React name like we do for attributes that exist only in HTML.
|
|
2910
|
+
['tabIndex', 'crossOrigin'].forEach(function (attributeName) {
|
|
2911
|
+
properties[attributeName] = new PropertyInfoRecord(attributeName, STRING, false, // mustUseProperty
|
|
2912
|
+
attributeName.toLowerCase(), // attributeName
|
|
2913
|
+
null);
|
|
2914
|
+
} // attributeNamespace
|
|
2915
|
+
);
|
|
2912
2916
|
|
|
2913
2917
|
/**
|
|
2914
2918
|
* Get the value for a property on a node. Only used in DEV for SSR validation.
|
|
@@ -3147,7 +3151,7 @@ var enableProfilerTimer = true;
|
|
|
3147
3151
|
var enableSchedulerTracing = true;
|
|
3148
3152
|
|
|
3149
3153
|
// Only used in www builds.
|
|
3150
|
-
// TODO: true? Here it might just be false.
|
|
3154
|
+
var enableSuspenseServerRenderer = false; // TODO: true? Here it might just be false.
|
|
3151
3155
|
|
|
3152
3156
|
// Only used in www builds.
|
|
3153
3157
|
|
|
@@ -8622,6 +8626,9 @@ var SUPPRESS_HYDRATION_WARNING = void 0;
|
|
|
8622
8626
|
SUPPRESS_HYDRATION_WARNING = 'suppressHydrationWarning';
|
|
8623
8627
|
}
|
|
8624
8628
|
|
|
8629
|
+
var SUSPENSE_START_DATA = '$';
|
|
8630
|
+
var SUSPENSE_END_DATA = '/$';
|
|
8631
|
+
|
|
8625
8632
|
var STYLE = 'style';
|
|
8626
8633
|
|
|
8627
8634
|
var eventsEnabled = null;
|
|
@@ -8850,6 +8857,43 @@ function removeChildFromContainer(container, child) {
|
|
|
8850
8857
|
}
|
|
8851
8858
|
}
|
|
8852
8859
|
|
|
8860
|
+
function clearSuspenseBoundary(parentInstance, suspenseInstance) {
|
|
8861
|
+
var node = suspenseInstance;
|
|
8862
|
+
// Delete all nodes within this suspense boundary.
|
|
8863
|
+
// There might be nested nodes so we need to keep track of how
|
|
8864
|
+
// deep we are and only break out when we're back on top.
|
|
8865
|
+
var depth = 0;
|
|
8866
|
+
do {
|
|
8867
|
+
var nextNode = node.nextSibling;
|
|
8868
|
+
parentInstance.removeChild(node);
|
|
8869
|
+
if (nextNode && nextNode.nodeType === COMMENT_NODE) {
|
|
8870
|
+
var data = nextNode.data;
|
|
8871
|
+
if (data === SUSPENSE_END_DATA) {
|
|
8872
|
+
if (depth === 0) {
|
|
8873
|
+
parentInstance.removeChild(nextNode);
|
|
8874
|
+
return;
|
|
8875
|
+
} else {
|
|
8876
|
+
depth--;
|
|
8877
|
+
}
|
|
8878
|
+
} else if (data === SUSPENSE_START_DATA) {
|
|
8879
|
+
depth++;
|
|
8880
|
+
}
|
|
8881
|
+
}
|
|
8882
|
+
node = nextNode;
|
|
8883
|
+
} while (node);
|
|
8884
|
+
// TODO: Warn, we didn't find the end comment boundary.
|
|
8885
|
+
}
|
|
8886
|
+
|
|
8887
|
+
function clearSuspenseBoundaryFromContainer(container, suspenseInstance) {
|
|
8888
|
+
if (container.nodeType === COMMENT_NODE) {
|
|
8889
|
+
clearSuspenseBoundary(container.parentNode, suspenseInstance);
|
|
8890
|
+
} else if (container.nodeType === ELEMENT_NODE) {
|
|
8891
|
+
clearSuspenseBoundary(container, suspenseInstance);
|
|
8892
|
+
} else {
|
|
8893
|
+
// Document nodes should never contain suspense boundaries.
|
|
8894
|
+
}
|
|
8895
|
+
}
|
|
8896
|
+
|
|
8853
8897
|
function hideInstance(instance) {
|
|
8854
8898
|
// TODO: Does this work for all element types? What about MathML? Should we
|
|
8855
8899
|
// pass host context to this method?
|
|
@@ -8895,10 +8939,19 @@ function canHydrateTextInstance(instance, text) {
|
|
|
8895
8939
|
return instance;
|
|
8896
8940
|
}
|
|
8897
8941
|
|
|
8942
|
+
function canHydrateSuspenseInstance(instance) {
|
|
8943
|
+
if (instance.nodeType !== COMMENT_NODE) {
|
|
8944
|
+
// Empty strings are not parsed by HTML so there won't be a correct match here.
|
|
8945
|
+
return null;
|
|
8946
|
+
}
|
|
8947
|
+
// This has now been refined to a suspense node.
|
|
8948
|
+
return instance;
|
|
8949
|
+
}
|
|
8950
|
+
|
|
8898
8951
|
function getNextHydratableSibling(instance) {
|
|
8899
8952
|
var node = instance.nextSibling;
|
|
8900
8953
|
// Skip non-hydratable nodes.
|
|
8901
|
-
while (node && node.nodeType !== ELEMENT_NODE && node.nodeType !== TEXT_NODE) {
|
|
8954
|
+
while (node && node.nodeType !== ELEMENT_NODE && node.nodeType !== TEXT_NODE && (!enableSuspenseServerRenderer || node.nodeType !== COMMENT_NODE || node.data !== SUSPENSE_START_DATA)) {
|
|
8902
8955
|
node = node.nextSibling;
|
|
8903
8956
|
}
|
|
8904
8957
|
return node;
|
|
@@ -8907,7 +8960,7 @@ function getNextHydratableSibling(instance) {
|
|
|
8907
8960
|
function getFirstHydratableChild(parentInstance) {
|
|
8908
8961
|
var next = parentInstance.firstChild;
|
|
8909
8962
|
// Skip non-hydratable nodes.
|
|
8910
|
-
while (next && next.nodeType !== ELEMENT_NODE && next.nodeType !== TEXT_NODE) {
|
|
8963
|
+
while (next && next.nodeType !== ELEMENT_NODE && next.nodeType !== TEXT_NODE && (!enableSuspenseServerRenderer || next.nodeType !== COMMENT_NODE || next.data !== SUSPENSE_START_DATA)) {
|
|
8911
8964
|
next = next.nextSibling;
|
|
8912
8965
|
}
|
|
8913
8966
|
return next;
|
|
@@ -8931,6 +8984,31 @@ function hydrateTextInstance(textInstance, text, internalInstanceHandle) {
|
|
|
8931
8984
|
return diffHydratedText(textInstance, text);
|
|
8932
8985
|
}
|
|
8933
8986
|
|
|
8987
|
+
function getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance) {
|
|
8988
|
+
var node = suspenseInstance.nextSibling;
|
|
8989
|
+
// Skip past all nodes within this suspense boundary.
|
|
8990
|
+
// There might be nested nodes so we need to keep track of how
|
|
8991
|
+
// deep we are and only break out when we're back on top.
|
|
8992
|
+
var depth = 0;
|
|
8993
|
+
while (node) {
|
|
8994
|
+
if (node.nodeType === COMMENT_NODE) {
|
|
8995
|
+
var data = node.data;
|
|
8996
|
+
if (data === SUSPENSE_END_DATA) {
|
|
8997
|
+
if (depth === 0) {
|
|
8998
|
+
return getNextHydratableSibling(node);
|
|
8999
|
+
} else {
|
|
9000
|
+
depth--;
|
|
9001
|
+
}
|
|
9002
|
+
} else if (data === SUSPENSE_START_DATA) {
|
|
9003
|
+
depth++;
|
|
9004
|
+
}
|
|
9005
|
+
}
|
|
9006
|
+
node = node.nextSibling;
|
|
9007
|
+
}
|
|
9008
|
+
// TODO: Warn, we didn't find the end comment boundary.
|
|
9009
|
+
return null;
|
|
9010
|
+
}
|
|
9011
|
+
|
|
8934
9012
|
function didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, text) {
|
|
8935
9013
|
{
|
|
8936
9014
|
warnForUnmatchedText(textInstance, text);
|
|
@@ -8947,6 +9025,8 @@ function didNotHydrateContainerInstance(parentContainer, instance) {
|
|
|
8947
9025
|
{
|
|
8948
9026
|
if (instance.nodeType === ELEMENT_NODE) {
|
|
8949
9027
|
warnForDeletedHydratableElement(parentContainer, instance);
|
|
9028
|
+
} else if (instance.nodeType === COMMENT_NODE) {
|
|
9029
|
+
// TODO: warnForDeletedHydratableSuspenseBoundary
|
|
8950
9030
|
} else {
|
|
8951
9031
|
warnForDeletedHydratableText(parentContainer, instance);
|
|
8952
9032
|
}
|
|
@@ -8957,6 +9037,8 @@ function didNotHydrateInstance(parentType, parentProps, parentInstance, instance
|
|
|
8957
9037
|
if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
|
|
8958
9038
|
if (instance.nodeType === ELEMENT_NODE) {
|
|
8959
9039
|
warnForDeletedHydratableElement(parentInstance, instance);
|
|
9040
|
+
} else if (instance.nodeType === COMMENT_NODE) {
|
|
9041
|
+
// TODO: warnForDeletedHydratableSuspenseBoundary
|
|
8960
9042
|
} else {
|
|
8961
9043
|
warnForDeletedHydratableText(parentInstance, instance);
|
|
8962
9044
|
}
|
|
@@ -8975,6 +9057,8 @@ function didNotFindHydratableContainerTextInstance(parentContainer, text) {
|
|
|
8975
9057
|
}
|
|
8976
9058
|
}
|
|
8977
9059
|
|
|
9060
|
+
|
|
9061
|
+
|
|
8978
9062
|
function didNotFindHydratableInstance(parentType, parentProps, parentInstance, type, props) {
|
|
8979
9063
|
if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
|
|
8980
9064
|
warnForInsertedHydratedElement(parentInstance, type, props);
|
|
@@ -8987,6 +9071,12 @@ function didNotFindHydratableTextInstance(parentType, parentProps, parentInstanc
|
|
|
8987
9071
|
}
|
|
8988
9072
|
}
|
|
8989
9073
|
|
|
9074
|
+
function didNotFindHydratableSuspenseInstance(parentType, parentProps, parentInstance) {
|
|
9075
|
+
if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
|
|
9076
|
+
// TODO: warnForInsertedHydratedSuspense(parentInstance);
|
|
9077
|
+
}
|
|
9078
|
+
}
|
|
9079
|
+
|
|
8990
9080
|
// Prefix measurements so that it's possible to filter them.
|
|
8991
9081
|
// Longer prefixes are hard to read in DevTools.
|
|
8992
9082
|
var reactEmoji = '\u269B';
|
|
@@ -9242,7 +9332,7 @@ function stopFailedWorkTimer(fiber) {
|
|
|
9242
9332
|
return;
|
|
9243
9333
|
}
|
|
9244
9334
|
fiber._debugIsCurrentlyTiming = false;
|
|
9245
|
-
var warning = fiber.tag === SuspenseComponent ? 'Rendering was suspended' : 'An error was thrown inside this error boundary';
|
|
9335
|
+
var warning = fiber.tag === SuspenseComponent || fiber.tag === DehydratedSuspenseComponent ? 'Rendering was suspended' : 'An error was thrown inside this error boundary';
|
|
9246
9336
|
endFiberMark(fiber, null, warning);
|
|
9247
9337
|
}
|
|
9248
9338
|
}
|
|
@@ -12049,7 +12139,7 @@ function ChildReconciler(shouldTrackSideEffects) {
|
|
|
12049
12139
|
}
|
|
12050
12140
|
|
|
12051
12141
|
function reconcileChildrenArray(returnFiber, currentFirstChild, newChildren, expirationTime) {
|
|
12052
|
-
// This algorithm can't optimize by searching from
|
|
12142
|
+
// This algorithm can't optimize by searching from both ends since we
|
|
12053
12143
|
// don't have backpointers on fibers. I'm trying to see how far we can get
|
|
12054
12144
|
// with that model. If it ends up not being worth the tradeoffs, we can
|
|
12055
12145
|
// add it later.
|
|
@@ -12863,9 +12953,6 @@ function mountWorkInProgressHook() {
|
|
|
12863
12953
|
|
|
12864
12954
|
{
|
|
12865
12955
|
hook._debugType = currentHookNameInDev;
|
|
12866
|
-
if (currentlyRenderingFiber$1 !== null && currentlyRenderingFiber$1.alternate !== null) {
|
|
12867
|
-
warning$1(false, '%s: Rendered more hooks than during the previous render. This is ' + 'not currently supported and may lead to unexpected behavior.', getComponentName(currentlyRenderingFiber$1.type));
|
|
12868
|
-
}
|
|
12869
12956
|
}
|
|
12870
12957
|
if (workInProgressHook === null) {
|
|
12871
12958
|
// This is the first hook in the list
|
|
@@ -13228,7 +13315,7 @@ function mountImperativeHandle(ref, create, deps) {
|
|
|
13228
13315
|
}
|
|
13229
13316
|
|
|
13230
13317
|
// TODO: If deps are provided, should we skip comparing the ref itself?
|
|
13231
|
-
var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) :
|
|
13318
|
+
var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
|
|
13232
13319
|
|
|
13233
13320
|
return mountEffectImpl(Update, UnmountMutation | MountLayout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
|
|
13234
13321
|
}
|
|
@@ -13239,7 +13326,7 @@ function updateImperativeHandle(ref, create, deps) {
|
|
|
13239
13326
|
}
|
|
13240
13327
|
|
|
13241
13328
|
// TODO: If deps are provided, should we skip comparing the ref itself?
|
|
13242
|
-
var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) :
|
|
13329
|
+
var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
|
|
13243
13330
|
|
|
13244
13331
|
return updateEffectImpl(Update, UnmountMutation | MountLayout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
|
|
13245
13332
|
}
|
|
@@ -13306,7 +13393,7 @@ function updateMemo(nextCreate, deps) {
|
|
|
13306
13393
|
var shouldWarnForUnbatchedSetState = false;
|
|
13307
13394
|
|
|
13308
13395
|
{
|
|
13309
|
-
// jest
|
|
13396
|
+
// jest isn't a 'global', it's just exposed to tests via a wrapped function
|
|
13310
13397
|
// further, this isn't a test file, so flow doesn't recognize the symbol. So...
|
|
13311
13398
|
// $FlowExpectedError - because requirements don't give a damn about your type sigs.
|
|
13312
13399
|
if ('undefined' !== typeof jest) {
|
|
@@ -13796,6 +13883,18 @@ function enterHydrationState(fiber) {
|
|
|
13796
13883
|
return true;
|
|
13797
13884
|
}
|
|
13798
13885
|
|
|
13886
|
+
function reenterHydrationStateFromDehydratedSuspenseInstance(fiber) {
|
|
13887
|
+
if (!supportsHydration) {
|
|
13888
|
+
return false;
|
|
13889
|
+
}
|
|
13890
|
+
|
|
13891
|
+
var suspenseInstance = fiber.stateNode;
|
|
13892
|
+
nextHydratableInstance = getNextHydratableSibling(suspenseInstance);
|
|
13893
|
+
popToNextHostParent(fiber);
|
|
13894
|
+
isHydrating = true;
|
|
13895
|
+
return true;
|
|
13896
|
+
}
|
|
13897
|
+
|
|
13799
13898
|
function deleteHydratableInstance(returnFiber, instance) {
|
|
13800
13899
|
{
|
|
13801
13900
|
switch (returnFiber.tag) {
|
|
@@ -13842,6 +13941,9 @@ function insertNonHydratedInstance(returnFiber, fiber) {
|
|
|
13842
13941
|
case HostText:
|
|
13843
13942
|
var text = fiber.pendingProps;
|
|
13844
13943
|
didNotFindHydratableContainerTextInstance(parentContainer, text);
|
|
13944
|
+
break;
|
|
13945
|
+
case SuspenseComponent:
|
|
13946
|
+
|
|
13845
13947
|
break;
|
|
13846
13948
|
}
|
|
13847
13949
|
break;
|
|
@@ -13861,6 +13963,9 @@ function insertNonHydratedInstance(returnFiber, fiber) {
|
|
|
13861
13963
|
var _text = fiber.pendingProps;
|
|
13862
13964
|
didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, _text);
|
|
13863
13965
|
break;
|
|
13966
|
+
case SuspenseComponent:
|
|
13967
|
+
didNotFindHydratableSuspenseInstance(parentType, parentProps, parentInstance);
|
|
13968
|
+
break;
|
|
13864
13969
|
}
|
|
13865
13970
|
break;
|
|
13866
13971
|
}
|
|
@@ -13893,6 +13998,19 @@ function tryHydrate(fiber, nextInstance) {
|
|
|
13893
13998
|
}
|
|
13894
13999
|
return false;
|
|
13895
14000
|
}
|
|
14001
|
+
case SuspenseComponent:
|
|
14002
|
+
{
|
|
14003
|
+
if (enableSuspenseServerRenderer) {
|
|
14004
|
+
var suspenseInstance = canHydrateSuspenseInstance(nextInstance);
|
|
14005
|
+
if (suspenseInstance !== null) {
|
|
14006
|
+
// Downgrade the tag to a dehydrated component until we've hydrated it.
|
|
14007
|
+
fiber.tag = DehydratedSuspenseComponent;
|
|
14008
|
+
fiber.stateNode = suspenseInstance;
|
|
14009
|
+
return true;
|
|
14010
|
+
}
|
|
14011
|
+
}
|
|
14012
|
+
return false;
|
|
14013
|
+
}
|
|
13896
14014
|
default:
|
|
13897
14015
|
return false;
|
|
13898
14016
|
}
|
|
@@ -13986,9 +14104,18 @@ function prepareToHydrateHostTextInstance(fiber) {
|
|
|
13986
14104
|
return shouldUpdate;
|
|
13987
14105
|
}
|
|
13988
14106
|
|
|
14107
|
+
function skipPastDehydratedSuspenseInstance(fiber) {
|
|
14108
|
+
if (!supportsHydration) {
|
|
14109
|
+
invariant(false, 'Expected skipPastDehydratedSuspenseInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.');
|
|
14110
|
+
}
|
|
14111
|
+
var suspenseInstance = fiber.stateNode;
|
|
14112
|
+
!suspenseInstance ? invariant(false, 'Expected to have a hydrated suspense instance. This error is likely caused by a bug in React. Please file an issue.') : void 0;
|
|
14113
|
+
nextHydratableInstance = getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance);
|
|
14114
|
+
}
|
|
14115
|
+
|
|
13989
14116
|
function popToNextHostParent(fiber) {
|
|
13990
14117
|
var parent = fiber.return;
|
|
13991
|
-
while (parent !== null && parent.tag !== HostComponent && parent.tag !== HostRoot) {
|
|
14118
|
+
while (parent !== null && parent.tag !== HostComponent && parent.tag !== HostRoot && parent.tag !== DehydratedSuspenseComponent) {
|
|
13992
14119
|
parent = parent.return;
|
|
13993
14120
|
}
|
|
13994
14121
|
hydrationParentFiber = parent;
|
|
@@ -14096,6 +14223,10 @@ function forceUnmountCurrentAndReconcile(current$$1, workInProgress, nextChildre
|
|
|
14096
14223
|
}
|
|
14097
14224
|
|
|
14098
14225
|
function updateForwardRef(current$$1, workInProgress, Component, nextProps, renderExpirationTime) {
|
|
14226
|
+
// TODO: current can be non-null here even if the component
|
|
14227
|
+
// hasn't yet mounted. This happens after the first render suspends.
|
|
14228
|
+
// We'll need to figure out if this is fine or can cause issues.
|
|
14229
|
+
|
|
14099
14230
|
{
|
|
14100
14231
|
if (workInProgress.type !== workInProgress.elementType) {
|
|
14101
14232
|
// Lazy component props can't be validated in createElement
|
|
@@ -14201,6 +14332,10 @@ function updateMemoComponent(current$$1, workInProgress, Component, nextProps, u
|
|
|
14201
14332
|
}
|
|
14202
14333
|
|
|
14203
14334
|
function updateSimpleMemoComponent(current$$1, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
|
|
14335
|
+
// TODO: current can be non-null here even if the component
|
|
14336
|
+
// hasn't yet mounted. This happens when the inner render suspends.
|
|
14337
|
+
// We'll need to figure out if this is fine or can cause issues.
|
|
14338
|
+
|
|
14204
14339
|
{
|
|
14205
14340
|
if (workInProgress.type !== workInProgress.elementType) {
|
|
14206
14341
|
// Lazy component props can't be validated in createElement
|
|
@@ -14824,6 +14959,18 @@ function updateSuspenseComponent(current$$1, workInProgress, renderExpirationTim
|
|
|
14824
14959
|
// children -- we skip over the primary children entirely.
|
|
14825
14960
|
var next = void 0;
|
|
14826
14961
|
if (current$$1 === null) {
|
|
14962
|
+
if (enableSuspenseServerRenderer) {
|
|
14963
|
+
// If we're currently hydrating, try to hydrate this boundary.
|
|
14964
|
+
// But only if this has a fallback.
|
|
14965
|
+
if (nextProps.fallback !== undefined) {
|
|
14966
|
+
tryToClaimNextHydratableInstance(workInProgress);
|
|
14967
|
+
// This could've changed the tag if this was a dehydrated suspense component.
|
|
14968
|
+
if (workInProgress.tag === DehydratedSuspenseComponent) {
|
|
14969
|
+
return updateDehydratedSuspenseComponent(null, workInProgress, renderExpirationTime);
|
|
14970
|
+
}
|
|
14971
|
+
}
|
|
14972
|
+
}
|
|
14973
|
+
|
|
14827
14974
|
// This is the initial mount. This branch is pretty simple because there's
|
|
14828
14975
|
// no previous state that needs to be preserved.
|
|
14829
14976
|
if (nextDidTimeout) {
|
|
@@ -14975,6 +15122,65 @@ function updateSuspenseComponent(current$$1, workInProgress, renderExpirationTim
|
|
|
14975
15122
|
return next;
|
|
14976
15123
|
}
|
|
14977
15124
|
|
|
15125
|
+
function updateDehydratedSuspenseComponent(current$$1, workInProgress, renderExpirationTime) {
|
|
15126
|
+
if (current$$1 === null) {
|
|
15127
|
+
// During the first pass, we'll bail out and not drill into the children.
|
|
15128
|
+
// Instead, we'll leave the content in place and try to hydrate it later.
|
|
15129
|
+
workInProgress.expirationTime = Never;
|
|
15130
|
+
return null;
|
|
15131
|
+
}
|
|
15132
|
+
// We use childExpirationTime to indicate that a child might depend on context, so if
|
|
15133
|
+
// any context has changed, we need to treat is as if the input might have changed.
|
|
15134
|
+
var hasContextChanged$$1 = current$$1.childExpirationTime >= renderExpirationTime;
|
|
15135
|
+
if (didReceiveUpdate || hasContextChanged$$1) {
|
|
15136
|
+
// This boundary has changed since the first render. This means that we are now unable to
|
|
15137
|
+
// hydrate it. We might still be able to hydrate it using an earlier expiration time but
|
|
15138
|
+
// during this render we can't. Instead, we're going to delete the whole subtree and
|
|
15139
|
+
// instead inject a new real Suspense boundary to take its place, which may render content
|
|
15140
|
+
// or fallback. The real Suspense boundary will suspend for a while so we have some time
|
|
15141
|
+
// to ensure it can produce real content, but all state and pending events will be lost.
|
|
15142
|
+
|
|
15143
|
+
// Detach from the current dehydrated boundary.
|
|
15144
|
+
current$$1.alternate = null;
|
|
15145
|
+
workInProgress.alternate = null;
|
|
15146
|
+
|
|
15147
|
+
// Insert a deletion in the effect list.
|
|
15148
|
+
var returnFiber = workInProgress.return;
|
|
15149
|
+
!(returnFiber !== null) ? invariant(false, 'Suspense boundaries are never on the root. This is probably a bug in React.') : void 0;
|
|
15150
|
+
var last = returnFiber.lastEffect;
|
|
15151
|
+
if (last !== null) {
|
|
15152
|
+
last.nextEffect = current$$1;
|
|
15153
|
+
returnFiber.lastEffect = current$$1;
|
|
15154
|
+
} else {
|
|
15155
|
+
returnFiber.firstEffect = returnFiber.lastEffect = current$$1;
|
|
15156
|
+
}
|
|
15157
|
+
current$$1.nextEffect = null;
|
|
15158
|
+
current$$1.effectTag = Deletion;
|
|
15159
|
+
|
|
15160
|
+
// Upgrade this work in progress to a real Suspense component.
|
|
15161
|
+
workInProgress.tag = SuspenseComponent;
|
|
15162
|
+
workInProgress.stateNode = null;
|
|
15163
|
+
workInProgress.memoizedState = null;
|
|
15164
|
+
// This is now an insertion.
|
|
15165
|
+
workInProgress.effectTag |= Placement;
|
|
15166
|
+
// Retry as a real Suspense component.
|
|
15167
|
+
return updateSuspenseComponent(null, workInProgress, renderExpirationTime);
|
|
15168
|
+
}
|
|
15169
|
+
if ((workInProgress.effectTag & DidCapture) === NoEffect) {
|
|
15170
|
+
// This is the first attempt.
|
|
15171
|
+
reenterHydrationStateFromDehydratedSuspenseInstance(workInProgress);
|
|
15172
|
+
var nextProps = workInProgress.pendingProps;
|
|
15173
|
+
var nextChildren = nextProps.children;
|
|
15174
|
+
workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
|
|
15175
|
+
return workInProgress.child;
|
|
15176
|
+
} else {
|
|
15177
|
+
// Something suspended. Leave the existing children in place.
|
|
15178
|
+
// TODO: In non-concurrent mode, should we commit the nodes we have hydrated so far?
|
|
15179
|
+
workInProgress.child = null;
|
|
15180
|
+
return null;
|
|
15181
|
+
}
|
|
15182
|
+
}
|
|
15183
|
+
|
|
14978
15184
|
function updatePortalComponent(current$$1, workInProgress, renderExpirationTime) {
|
|
14979
15185
|
pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
|
|
14980
15186
|
var nextChildren = workInProgress.pendingProps;
|
|
@@ -15186,6 +15392,16 @@ function beginWork(current$$1, workInProgress, renderExpirationTime) {
|
|
|
15186
15392
|
}
|
|
15187
15393
|
break;
|
|
15188
15394
|
}
|
|
15395
|
+
case DehydratedSuspenseComponent:
|
|
15396
|
+
{
|
|
15397
|
+
if (enableSuspenseServerRenderer) {
|
|
15398
|
+
// We know that this component will suspend again because if it has
|
|
15399
|
+
// been unsuspended it has committed as a regular Suspense component.
|
|
15400
|
+
// If it needs to be retried, it should have work scheduled on it.
|
|
15401
|
+
workInProgress.effectTag |= DidCapture;
|
|
15402
|
+
break;
|
|
15403
|
+
}
|
|
15404
|
+
}
|
|
15189
15405
|
}
|
|
15190
15406
|
return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
|
|
15191
15407
|
}
|
|
@@ -15277,9 +15493,15 @@ function beginWork(current$$1, workInProgress, renderExpirationTime) {
|
|
|
15277
15493
|
var _resolvedProps4 = workInProgress.elementType === _Component3 ? _unresolvedProps4 : resolveDefaultProps(_Component3, _unresolvedProps4);
|
|
15278
15494
|
return mountIncompleteClassComponent(current$$1, workInProgress, _Component3, _resolvedProps4, renderExpirationTime);
|
|
15279
15495
|
}
|
|
15280
|
-
|
|
15281
|
-
|
|
15496
|
+
case DehydratedSuspenseComponent:
|
|
15497
|
+
{
|
|
15498
|
+
if (enableSuspenseServerRenderer) {
|
|
15499
|
+
return updateDehydratedSuspenseComponent(current$$1, workInProgress, renderExpirationTime);
|
|
15500
|
+
}
|
|
15501
|
+
break;
|
|
15502
|
+
}
|
|
15282
15503
|
}
|
|
15504
|
+
invariant(false, 'Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.');
|
|
15283
15505
|
}
|
|
15284
15506
|
|
|
15285
15507
|
var valueCursor = createCursor(null);
|
|
@@ -15368,6 +15590,28 @@ function calculateChangedBits(context, newValue, oldValue) {
|
|
|
15368
15590
|
}
|
|
15369
15591
|
}
|
|
15370
15592
|
|
|
15593
|
+
function scheduleWorkOnParentPath(parent, renderExpirationTime) {
|
|
15594
|
+
// Update the child expiration time of all the ancestors, including
|
|
15595
|
+
// the alternates.
|
|
15596
|
+
var node = parent;
|
|
15597
|
+
while (node !== null) {
|
|
15598
|
+
var alternate = node.alternate;
|
|
15599
|
+
if (node.childExpirationTime < renderExpirationTime) {
|
|
15600
|
+
node.childExpirationTime = renderExpirationTime;
|
|
15601
|
+
if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
|
|
15602
|
+
alternate.childExpirationTime = renderExpirationTime;
|
|
15603
|
+
}
|
|
15604
|
+
} else if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
|
|
15605
|
+
alternate.childExpirationTime = renderExpirationTime;
|
|
15606
|
+
} else {
|
|
15607
|
+
// Neither alternate was updated, which means the rest of the
|
|
15608
|
+
// ancestor path already has sufficient priority.
|
|
15609
|
+
break;
|
|
15610
|
+
}
|
|
15611
|
+
node = node.return;
|
|
15612
|
+
}
|
|
15613
|
+
}
|
|
15614
|
+
|
|
15371
15615
|
function propagateContextChange(workInProgress, context, changedBits, renderExpirationTime) {
|
|
15372
15616
|
var fiber = workInProgress.child;
|
|
15373
15617
|
if (fiber !== null) {
|
|
@@ -15406,25 +15650,8 @@ function propagateContextChange(workInProgress, context, changedBits, renderExpi
|
|
|
15406
15650
|
if (alternate !== null && alternate.expirationTime < renderExpirationTime) {
|
|
15407
15651
|
alternate.expirationTime = renderExpirationTime;
|
|
15408
15652
|
}
|
|
15409
|
-
|
|
15410
|
-
|
|
15411
|
-
var node = fiber.return;
|
|
15412
|
-
while (node !== null) {
|
|
15413
|
-
alternate = node.alternate;
|
|
15414
|
-
if (node.childExpirationTime < renderExpirationTime) {
|
|
15415
|
-
node.childExpirationTime = renderExpirationTime;
|
|
15416
|
-
if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
|
|
15417
|
-
alternate.childExpirationTime = renderExpirationTime;
|
|
15418
|
-
}
|
|
15419
|
-
} else if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
|
|
15420
|
-
alternate.childExpirationTime = renderExpirationTime;
|
|
15421
|
-
} else {
|
|
15422
|
-
// Neither alternate was updated, which means the rest of the
|
|
15423
|
-
// ancestor path already has sufficient priority.
|
|
15424
|
-
break;
|
|
15425
|
-
}
|
|
15426
|
-
node = node.return;
|
|
15427
|
-
}
|
|
15653
|
+
|
|
15654
|
+
scheduleWorkOnParentPath(fiber.return, renderExpirationTime);
|
|
15428
15655
|
|
|
15429
15656
|
// Mark the expiration time on the list, too.
|
|
15430
15657
|
if (list.expirationTime < renderExpirationTime) {
|
|
@@ -15440,6 +15667,23 @@ function propagateContextChange(workInProgress, context, changedBits, renderExpi
|
|
|
15440
15667
|
} else if (fiber.tag === ContextProvider) {
|
|
15441
15668
|
// Don't scan deeper if this is a matching provider
|
|
15442
15669
|
nextFiber = fiber.type === workInProgress.type ? null : fiber.child;
|
|
15670
|
+
} else if (enableSuspenseServerRenderer && fiber.tag === DehydratedSuspenseComponent) {
|
|
15671
|
+
// If a dehydrated suspense component is in this subtree, we don't know
|
|
15672
|
+
// if it will have any context consumers in it. The best we can do is
|
|
15673
|
+
// mark it as having updates on its children.
|
|
15674
|
+
if (fiber.expirationTime < renderExpirationTime) {
|
|
15675
|
+
fiber.expirationTime = renderExpirationTime;
|
|
15676
|
+
}
|
|
15677
|
+
var _alternate = fiber.alternate;
|
|
15678
|
+
if (_alternate !== null && _alternate.expirationTime < renderExpirationTime) {
|
|
15679
|
+
_alternate.expirationTime = renderExpirationTime;
|
|
15680
|
+
}
|
|
15681
|
+
// This is intentionally passing this fiber as the parent
|
|
15682
|
+
// because we want to schedule this fiber as having work
|
|
15683
|
+
// on its children. We'll use the childExpirationTime on
|
|
15684
|
+
// this fiber to indicate that a context has changed.
|
|
15685
|
+
scheduleWorkOnParentPath(fiber, renderExpirationTime);
|
|
15686
|
+
nextFiber = fiber.sibling;
|
|
15443
15687
|
} else {
|
|
15444
15688
|
// Traverse down.
|
|
15445
15689
|
nextFiber = fiber.child;
|
|
@@ -16563,6 +16807,26 @@ function completeWork(current, workInProgress, renderExpirationTime) {
|
|
|
16563
16807
|
}
|
|
16564
16808
|
break;
|
|
16565
16809
|
}
|
|
16810
|
+
case DehydratedSuspenseComponent:
|
|
16811
|
+
{
|
|
16812
|
+
if (enableSuspenseServerRenderer) {
|
|
16813
|
+
if (current === null) {
|
|
16814
|
+
var _wasHydrated2 = popHydrationState(workInProgress);
|
|
16815
|
+
!_wasHydrated2 ? invariant(false, 'A dehydrated suspense component was completed without a hydrated node. This is probably a bug in React.') : void 0;
|
|
16816
|
+
skipPastDehydratedSuspenseInstance(workInProgress);
|
|
16817
|
+
} else if ((workInProgress.effectTag & DidCapture) === NoEffect) {
|
|
16818
|
+
// This boundary did not suspend so it's now hydrated.
|
|
16819
|
+
// To handle any future suspense cases, we're going to now upgrade it
|
|
16820
|
+
// to a Suspense component. We detach it from the existing current fiber.
|
|
16821
|
+
current.alternate = null;
|
|
16822
|
+
workInProgress.alternate = null;
|
|
16823
|
+
workInProgress.tag = SuspenseComponent;
|
|
16824
|
+
workInProgress.memoizedState = null;
|
|
16825
|
+
workInProgress.stateNode = null;
|
|
16826
|
+
}
|
|
16827
|
+
}
|
|
16828
|
+
break;
|
|
16829
|
+
}
|
|
16566
16830
|
default:
|
|
16567
16831
|
invariant(false, 'Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.');
|
|
16568
16832
|
}
|
|
@@ -16653,7 +16917,7 @@ var didWarnAboutUndefinedSnapshotBeforeUpdate = null;
|
|
|
16653
16917
|
didWarnAboutUndefinedSnapshotBeforeUpdate = new Set();
|
|
16654
16918
|
}
|
|
16655
16919
|
|
|
16656
|
-
var PossiblyWeakSet = typeof WeakSet === 'function' ? WeakSet : Set;
|
|
16920
|
+
var PossiblyWeakSet$1 = typeof WeakSet === 'function' ? WeakSet : Set;
|
|
16657
16921
|
|
|
16658
16922
|
function logError(boundary, errorInfo) {
|
|
16659
16923
|
var source = errorInfo.source;
|
|
@@ -16966,7 +17230,7 @@ function commitLifeCycles(finishedRoot, current$$1, finishedWork, committedExpir
|
|
|
16966
17230
|
|
|
16967
17231
|
function hideOrUnhideAllChildren(finishedWork, isHidden) {
|
|
16968
17232
|
if (supportsMutation) {
|
|
16969
|
-
// We only have the top Fiber that was inserted but we need recurse down its
|
|
17233
|
+
// We only have the top Fiber that was inserted but we need to recurse down its
|
|
16970
17234
|
var node = finishedWork;
|
|
16971
17235
|
while (true) {
|
|
16972
17236
|
if (node.tag === HostComponent) {
|
|
@@ -17234,7 +17498,7 @@ function getHostSibling(fiber) {
|
|
|
17234
17498
|
}
|
|
17235
17499
|
node.sibling.return = node.return;
|
|
17236
17500
|
node = node.sibling;
|
|
17237
|
-
while (node.tag !== HostComponent && node.tag !== HostText) {
|
|
17501
|
+
while (node.tag !== HostComponent && node.tag !== HostText && node.tag !== DehydratedSuspenseComponent) {
|
|
17238
17502
|
// If it is not host node and, we might have a host node inside it.
|
|
17239
17503
|
// Try to search down until we find one.
|
|
17240
17504
|
if (node.effectTag & Placement) {
|
|
@@ -17294,7 +17558,7 @@ function commitPlacement(finishedWork) {
|
|
|
17294
17558
|
}
|
|
17295
17559
|
|
|
17296
17560
|
var before = getHostSibling(finishedWork);
|
|
17297
|
-
// We only have the top Fiber that was inserted but we need recurse down its
|
|
17561
|
+
// We only have the top Fiber that was inserted but we need to recurse down its
|
|
17298
17562
|
// children to find all the terminal nodes.
|
|
17299
17563
|
var node = finishedWork;
|
|
17300
17564
|
while (true) {
|
|
@@ -17336,7 +17600,7 @@ function commitPlacement(finishedWork) {
|
|
|
17336
17600
|
}
|
|
17337
17601
|
|
|
17338
17602
|
function unmountHostComponents(current$$1) {
|
|
17339
|
-
// We only have the top Fiber that was deleted but we need recurse down its
|
|
17603
|
+
// We only have the top Fiber that was deleted but we need to recurse down its
|
|
17340
17604
|
var node = current$$1;
|
|
17341
17605
|
|
|
17342
17606
|
// Each iteration, currentParent is populated with node's host parent if not
|
|
@@ -17381,13 +17645,20 @@ function unmountHostComponents(current$$1) {
|
|
|
17381
17645
|
removeChild(currentParent, node.stateNode);
|
|
17382
17646
|
}
|
|
17383
17647
|
// Don't visit children because we already visited them.
|
|
17648
|
+
} else if (enableSuspenseServerRenderer && node.tag === DehydratedSuspenseComponent) {
|
|
17649
|
+
// Delete the dehydrated suspense boundary and all of its content.
|
|
17650
|
+
if (currentParentIsContainer) {
|
|
17651
|
+
clearSuspenseBoundaryFromContainer(currentParent, node.stateNode);
|
|
17652
|
+
} else {
|
|
17653
|
+
clearSuspenseBoundary(currentParent, node.stateNode);
|
|
17654
|
+
}
|
|
17384
17655
|
} else if (node.tag === HostPortal) {
|
|
17385
|
-
// When we go into a portal, it becomes the parent to remove from.
|
|
17386
|
-
// We will reassign it back when we pop the portal on the way up.
|
|
17387
|
-
currentParent = node.stateNode.containerInfo;
|
|
17388
|
-
currentParentIsContainer = true;
|
|
17389
|
-
// Visit children because portals might contain host components.
|
|
17390
17656
|
if (node.child !== null) {
|
|
17657
|
+
// When we go into a portal, it becomes the parent to remove from.
|
|
17658
|
+
// We will reassign it back when we pop the portal on the way up.
|
|
17659
|
+
currentParent = node.stateNode.containerInfo;
|
|
17660
|
+
currentParentIsContainer = true;
|
|
17661
|
+
// Visit children because portals might contain host components.
|
|
17391
17662
|
node.child.return = node;
|
|
17392
17663
|
node = node.child;
|
|
17393
17664
|
continue;
|
|
@@ -17537,7 +17808,7 @@ function commitWork(current$$1, finishedWork) {
|
|
|
17537
17808
|
finishedWork.updateQueue = null;
|
|
17538
17809
|
var retryCache = finishedWork.stateNode;
|
|
17539
17810
|
if (retryCache === null) {
|
|
17540
|
-
retryCache = finishedWork.stateNode = new PossiblyWeakSet();
|
|
17811
|
+
retryCache = finishedWork.stateNode = new PossiblyWeakSet$1();
|
|
17541
17812
|
}
|
|
17542
17813
|
thenables.forEach(function (thenable) {
|
|
17543
17814
|
// Memoize using the boundary fiber to prevent redundant listeners.
|
|
@@ -17572,6 +17843,7 @@ function commitResetTextContent(current$$1) {
|
|
|
17572
17843
|
resetTextContent(current$$1.stateNode);
|
|
17573
17844
|
}
|
|
17574
17845
|
|
|
17846
|
+
var PossiblyWeakSet = typeof WeakSet === 'function' ? WeakSet : Set;
|
|
17575
17847
|
var PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map;
|
|
17576
17848
|
|
|
17577
17849
|
function createRootErrorUpdate(fiber, errorInfo, expirationTime) {
|
|
@@ -17630,6 +17902,34 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) {
|
|
|
17630
17902
|
return update;
|
|
17631
17903
|
}
|
|
17632
17904
|
|
|
17905
|
+
function attachPingListener(root, renderExpirationTime, thenable) {
|
|
17906
|
+
// Attach a listener to the promise to "ping" the root and retry. But
|
|
17907
|
+
// only if one does not already exist for the current render expiration
|
|
17908
|
+
// time (which acts like a "thread ID" here).
|
|
17909
|
+
var pingCache = root.pingCache;
|
|
17910
|
+
var threadIDs = void 0;
|
|
17911
|
+
if (pingCache === null) {
|
|
17912
|
+
pingCache = root.pingCache = new PossiblyWeakMap();
|
|
17913
|
+
threadIDs = new Set();
|
|
17914
|
+
pingCache.set(thenable, threadIDs);
|
|
17915
|
+
} else {
|
|
17916
|
+
threadIDs = pingCache.get(thenable);
|
|
17917
|
+
if (threadIDs === undefined) {
|
|
17918
|
+
threadIDs = new Set();
|
|
17919
|
+
pingCache.set(thenable, threadIDs);
|
|
17920
|
+
}
|
|
17921
|
+
}
|
|
17922
|
+
if (!threadIDs.has(renderExpirationTime)) {
|
|
17923
|
+
// Memoize using the thread ID to prevent redundant listeners.
|
|
17924
|
+
threadIDs.add(renderExpirationTime);
|
|
17925
|
+
var ping = pingSuspendedRoot.bind(null, root, thenable, renderExpirationTime);
|
|
17926
|
+
if (enableSchedulerTracing) {
|
|
17927
|
+
ping = tracing.unstable_wrap(ping);
|
|
17928
|
+
}
|
|
17929
|
+
thenable.then(ping, ping);
|
|
17930
|
+
}
|
|
17931
|
+
}
|
|
17932
|
+
|
|
17633
17933
|
function throwException(root, returnFiber, sourceFiber, value, renderExpirationTime) {
|
|
17634
17934
|
// The source fiber did not complete.
|
|
17635
17935
|
sourceFiber.effectTag |= Incomplete;
|
|
@@ -17671,6 +17971,9 @@ function throwException(root, returnFiber, sourceFiber, value, renderExpirationT
|
|
|
17671
17971
|
}
|
|
17672
17972
|
}
|
|
17673
17973
|
}
|
|
17974
|
+
// If there is a DehydratedSuspenseComponent we don't have to do anything because
|
|
17975
|
+
// if something suspends inside it, we will simply leave that as dehydrated. It
|
|
17976
|
+
// will never timeout.
|
|
17674
17977
|
_workInProgress = _workInProgress.return;
|
|
17675
17978
|
} while (_workInProgress !== null);
|
|
17676
17979
|
|
|
@@ -17734,31 +18037,7 @@ function throwException(root, returnFiber, sourceFiber, value, renderExpirationT
|
|
|
17734
18037
|
// Confirmed that the boundary is in a concurrent mode tree. Continue
|
|
17735
18038
|
// with the normal suspend path.
|
|
17736
18039
|
|
|
17737
|
-
|
|
17738
|
-
// only if one does not already exist for the current render expiration
|
|
17739
|
-
// time (which acts like a "thread ID" here).
|
|
17740
|
-
var pingCache = root.pingCache;
|
|
17741
|
-
var threadIDs = void 0;
|
|
17742
|
-
if (pingCache === null) {
|
|
17743
|
-
pingCache = root.pingCache = new PossiblyWeakMap();
|
|
17744
|
-
threadIDs = new Set();
|
|
17745
|
-
pingCache.set(thenable, threadIDs);
|
|
17746
|
-
} else {
|
|
17747
|
-
threadIDs = pingCache.get(thenable);
|
|
17748
|
-
if (threadIDs === undefined) {
|
|
17749
|
-
threadIDs = new Set();
|
|
17750
|
-
pingCache.set(thenable, threadIDs);
|
|
17751
|
-
}
|
|
17752
|
-
}
|
|
17753
|
-
if (!threadIDs.has(renderExpirationTime)) {
|
|
17754
|
-
// Memoize using the thread ID to prevent redundant listeners.
|
|
17755
|
-
threadIDs.add(renderExpirationTime);
|
|
17756
|
-
var ping = pingSuspendedRoot.bind(null, root, thenable, renderExpirationTime);
|
|
17757
|
-
if (enableSchedulerTracing) {
|
|
17758
|
-
ping = tracing.unstable_wrap(ping);
|
|
17759
|
-
}
|
|
17760
|
-
thenable.then(ping, ping);
|
|
17761
|
-
}
|
|
18040
|
+
attachPingListener(root, renderExpirationTime, thenable);
|
|
17762
18041
|
|
|
17763
18042
|
var absoluteTimeoutMs = void 0;
|
|
17764
18043
|
if (earliestTimeoutMs === -1) {
|
|
@@ -17790,6 +18069,29 @@ function throwException(root, returnFiber, sourceFiber, value, renderExpirationT
|
|
|
17790
18069
|
// whole tree.
|
|
17791
18070
|
renderDidSuspend(root, absoluteTimeoutMs, renderExpirationTime);
|
|
17792
18071
|
|
|
18072
|
+
_workInProgress.effectTag |= ShouldCapture;
|
|
18073
|
+
_workInProgress.expirationTime = renderExpirationTime;
|
|
18074
|
+
return;
|
|
18075
|
+
} else if (enableSuspenseServerRenderer && _workInProgress.tag === DehydratedSuspenseComponent) {
|
|
18076
|
+
attachPingListener(root, renderExpirationTime, thenable);
|
|
18077
|
+
|
|
18078
|
+
// Since we already have a current fiber, we can eagerly add a retry listener.
|
|
18079
|
+
var retryCache = _workInProgress.memoizedState;
|
|
18080
|
+
if (retryCache === null) {
|
|
18081
|
+
retryCache = _workInProgress.memoizedState = new PossiblyWeakSet();
|
|
18082
|
+
var _current = _workInProgress.alternate;
|
|
18083
|
+
!_current ? invariant(false, 'A dehydrated suspense boundary must commit before trying to render. This is probably a bug in React.') : void 0;
|
|
18084
|
+
_current.memoizedState = retryCache;
|
|
18085
|
+
}
|
|
18086
|
+
// Memoize using the boundary fiber to prevent redundant listeners.
|
|
18087
|
+
if (!retryCache.has(thenable)) {
|
|
18088
|
+
retryCache.add(thenable);
|
|
18089
|
+
var retry = retryTimedOutBoundary.bind(null, _workInProgress, thenable);
|
|
18090
|
+
if (enableSchedulerTracing) {
|
|
18091
|
+
retry = tracing.unstable_wrap(retry);
|
|
18092
|
+
}
|
|
18093
|
+
thenable.then(retry, retry);
|
|
18094
|
+
}
|
|
17793
18095
|
_workInProgress.effectTag |= ShouldCapture;
|
|
17794
18096
|
_workInProgress.expirationTime = renderExpirationTime;
|
|
17795
18097
|
return;
|
|
@@ -17867,6 +18169,7 @@ function unwindWork(workInProgress, renderExpirationTime) {
|
|
|
17867
18169
|
}
|
|
17868
18170
|
case HostComponent:
|
|
17869
18171
|
{
|
|
18172
|
+
// TODO: popHydrationState
|
|
17870
18173
|
popHostContext(workInProgress);
|
|
17871
18174
|
return null;
|
|
17872
18175
|
}
|
|
@@ -17880,6 +18183,19 @@ function unwindWork(workInProgress, renderExpirationTime) {
|
|
|
17880
18183
|
}
|
|
17881
18184
|
return null;
|
|
17882
18185
|
}
|
|
18186
|
+
case DehydratedSuspenseComponent:
|
|
18187
|
+
{
|
|
18188
|
+
if (enableSuspenseServerRenderer) {
|
|
18189
|
+
// TODO: popHydrationState
|
|
18190
|
+
var _effectTag3 = workInProgress.effectTag;
|
|
18191
|
+
if (_effectTag3 & ShouldCapture) {
|
|
18192
|
+
workInProgress.effectTag = _effectTag3 & ~ShouldCapture | DidCapture;
|
|
18193
|
+
// Captured a suspense effect. Re-render the boundary.
|
|
18194
|
+
return workInProgress;
|
|
18195
|
+
}
|
|
18196
|
+
}
|
|
18197
|
+
return null;
|
|
18198
|
+
}
|
|
17883
18199
|
case HostPortal:
|
|
17884
18200
|
popHostContainer(workInProgress);
|
|
17885
18201
|
return null;
|
|
@@ -17977,11 +18293,6 @@ if (enableSchedulerTracing) {
|
|
|
17977
18293
|
// Used to ensure computeUniqueAsyncExpiration is monotonically decreasing.
|
|
17978
18294
|
var lastUniqueAsyncExpiration = Sync - 1;
|
|
17979
18295
|
|
|
17980
|
-
// Represents the expiration time that incoming updates should use. (If this
|
|
17981
|
-
// is NoWork, use the default strategy: async updates in async mode, sync
|
|
17982
|
-
// updates in sync mode.)
|
|
17983
|
-
var expirationContext = NoWork;
|
|
17984
|
-
|
|
17985
18296
|
var isWorking = false;
|
|
17986
18297
|
|
|
17987
18298
|
// The next work in progress fiber that we're currently working on.
|
|
@@ -18277,6 +18588,10 @@ function commitPassiveEffects(root, firstEffect) {
|
|
|
18277
18588
|
if (rootExpirationTime !== NoWork) {
|
|
18278
18589
|
requestWork(root, rootExpirationTime);
|
|
18279
18590
|
}
|
|
18591
|
+
// Flush any sync work that was scheduled by effects
|
|
18592
|
+
if (!isBatchingUpdates && !isRendering) {
|
|
18593
|
+
performSyncWork();
|
|
18594
|
+
}
|
|
18280
18595
|
}
|
|
18281
18596
|
|
|
18282
18597
|
function isAlreadyFailedLegacyErrorBoundary(instance) {
|
|
@@ -18451,7 +18766,9 @@ function commitRoot(root, finishedWork) {
|
|
|
18451
18766
|
// here because that code is still in flux.
|
|
18452
18767
|
callback = tracing.unstable_wrap(callback);
|
|
18453
18768
|
}
|
|
18454
|
-
passiveEffectCallbackHandle =
|
|
18769
|
+
passiveEffectCallbackHandle = scheduler.unstable_runWithPriority(scheduler.unstable_NormalPriority, function () {
|
|
18770
|
+
return schedulePassiveEffects(callback);
|
|
18771
|
+
});
|
|
18455
18772
|
passiveEffectCallback = callback;
|
|
18456
18773
|
}
|
|
18457
18774
|
|
|
@@ -19040,7 +19357,7 @@ function renderRoot(root, isYieldy) {
|
|
|
19040
19357
|
return;
|
|
19041
19358
|
} else if (
|
|
19042
19359
|
// There's no lower priority work, but we're rendering asynchronously.
|
|
19043
|
-
//
|
|
19360
|
+
// Synchronously attempt to render the same level one more time. This is
|
|
19044
19361
|
// similar to a suspend, but without a timeout because we're not waiting
|
|
19045
19362
|
// for a promise to resolve.
|
|
19046
19363
|
!root.didError && isYieldy) {
|
|
@@ -19145,49 +19462,50 @@ function computeUniqueAsyncExpiration() {
|
|
|
19145
19462
|
}
|
|
19146
19463
|
|
|
19147
19464
|
function computeExpirationForFiber(currentTime, fiber) {
|
|
19465
|
+
var priorityLevel = scheduler.unstable_getCurrentPriorityLevel();
|
|
19466
|
+
|
|
19148
19467
|
var expirationTime = void 0;
|
|
19149
|
-
if (
|
|
19150
|
-
//
|
|
19151
|
-
expirationTime =
|
|
19152
|
-
} else if (isWorking) {
|
|
19153
|
-
|
|
19154
|
-
|
|
19155
|
-
// by default.
|
|
19156
|
-
expirationTime = Sync;
|
|
19157
|
-
} else {
|
|
19158
|
-
// Updates during the render phase should expire at the same time as
|
|
19159
|
-
// the work that is being rendered.
|
|
19160
|
-
expirationTime = nextRenderExpirationTime;
|
|
19161
|
-
}
|
|
19468
|
+
if ((fiber.mode & ConcurrentMode) === NoContext) {
|
|
19469
|
+
// Outside of concurrent mode, updates are always synchronous.
|
|
19470
|
+
expirationTime = Sync;
|
|
19471
|
+
} else if (isWorking && !isCommitting$1) {
|
|
19472
|
+
// During render phase, updates expire during as the current render.
|
|
19473
|
+
expirationTime = nextRenderExpirationTime;
|
|
19162
19474
|
} else {
|
|
19163
|
-
|
|
19164
|
-
|
|
19165
|
-
|
|
19166
|
-
|
|
19167
|
-
|
|
19475
|
+
switch (priorityLevel) {
|
|
19476
|
+
case scheduler.unstable_ImmediatePriority:
|
|
19477
|
+
expirationTime = Sync;
|
|
19478
|
+
break;
|
|
19479
|
+
case scheduler.unstable_UserBlockingPriority:
|
|
19168
19480
|
expirationTime = computeInteractiveExpiration(currentTime);
|
|
19169
|
-
|
|
19170
|
-
|
|
19481
|
+
break;
|
|
19482
|
+
case scheduler.unstable_NormalPriority:
|
|
19483
|
+
// This is a normal, concurrent update
|
|
19171
19484
|
expirationTime = computeAsyncExpiration(currentTime);
|
|
19172
|
-
|
|
19173
|
-
|
|
19174
|
-
|
|
19175
|
-
|
|
19176
|
-
|
|
19177
|
-
|
|
19178
|
-
|
|
19179
|
-
// This is a sync update
|
|
19180
|
-
expirationTime = Sync;
|
|
19485
|
+
break;
|
|
19486
|
+
case scheduler.unstable_LowPriority:
|
|
19487
|
+
case scheduler.unstable_IdlePriority:
|
|
19488
|
+
expirationTime = Never;
|
|
19489
|
+
break;
|
|
19490
|
+
default:
|
|
19491
|
+
invariant(false, 'Unknown priority level. This error is likely caused by a bug in React. Please file an issue.');
|
|
19181
19492
|
}
|
|
19182
|
-
|
|
19183
|
-
|
|
19184
|
-
//
|
|
19185
|
-
|
|
19186
|
-
|
|
19187
|
-
if (lowestPriorityPendingInteractiveExpirationTime === NoWork || expirationTime < lowestPriorityPendingInteractiveExpirationTime) {
|
|
19188
|
-
lowestPriorityPendingInteractiveExpirationTime = expirationTime;
|
|
19493
|
+
|
|
19494
|
+
// If we're in the middle of rendering a tree, do not update at the same
|
|
19495
|
+
// expiration time that is already rendering.
|
|
19496
|
+
if (nextRoot !== null && expirationTime === nextRenderExpirationTime) {
|
|
19497
|
+
expirationTime -= 1;
|
|
19189
19498
|
}
|
|
19190
19499
|
}
|
|
19500
|
+
|
|
19501
|
+
// Keep track of the lowest pending interactive expiration time. This
|
|
19502
|
+
// allows us to synchronously flush all interactive updates
|
|
19503
|
+
// when needed.
|
|
19504
|
+
// TODO: Move this to renderer?
|
|
19505
|
+
if (priorityLevel === scheduler.unstable_UserBlockingPriority && (lowestPriorityPendingInteractiveExpirationTime === NoWork || expirationTime < lowestPriorityPendingInteractiveExpirationTime)) {
|
|
19506
|
+
lowestPriorityPendingInteractiveExpirationTime = expirationTime;
|
|
19507
|
+
}
|
|
19508
|
+
|
|
19191
19509
|
return expirationTime;
|
|
19192
19510
|
}
|
|
19193
19511
|
|
|
@@ -19234,7 +19552,21 @@ function retryTimedOutBoundary(boundaryFiber, thenable) {
|
|
|
19234
19552
|
// The boundary fiber (a Suspense component) previously timed out and was
|
|
19235
19553
|
// rendered in its fallback state. One of the promises that suspended it has
|
|
19236
19554
|
// resolved, which means at least part of the tree was likely unblocked. Try
|
|
19237
|
-
var retryCache =
|
|
19555
|
+
var retryCache = void 0;
|
|
19556
|
+
if (enableSuspenseServerRenderer) {
|
|
19557
|
+
switch (boundaryFiber.tag) {
|
|
19558
|
+
case SuspenseComponent:
|
|
19559
|
+
retryCache = boundaryFiber.stateNode;
|
|
19560
|
+
break;
|
|
19561
|
+
case DehydratedSuspenseComponent:
|
|
19562
|
+
retryCache = boundaryFiber.memoizedState;
|
|
19563
|
+
break;
|
|
19564
|
+
default:
|
|
19565
|
+
invariant(false, 'Pinged unknown suspense boundary type. This is probably a bug in React.');
|
|
19566
|
+
}
|
|
19567
|
+
} else {
|
|
19568
|
+
retryCache = boundaryFiber.stateNode;
|
|
19569
|
+
}
|
|
19238
19570
|
if (retryCache !== null) {
|
|
19239
19571
|
// The thenable resolved, so we no longer need to memoize, because it will
|
|
19240
19572
|
// never be thrown again.
|
|
@@ -19333,7 +19665,7 @@ function scheduleWorkToRoot(fiber, expirationTime) {
|
|
|
19333
19665
|
function warnIfNotCurrentlyBatchingInDev(fiber) {
|
|
19334
19666
|
{
|
|
19335
19667
|
if (isRendering === false && isBatchingUpdates === false) {
|
|
19336
|
-
warningWithoutStack$1(false, 'An update to %s inside a test was not wrapped in act(...).\n\n' + 'When testing, code that causes React state updates should be wrapped into act(...):\n\n' + 'act(() => {\n' + ' /* fire events that update state */\n' + '});\n' + '/* assert on the output */\n\n' + "This ensures that you're testing the behavior the user would see in the browser." + ' Learn more at https://fb.me/react-wrap-tests-with-act', getComponentName(fiber.type));
|
|
19668
|
+
warningWithoutStack$1(false, 'An update to %s inside a test was not wrapped in act(...).\n\n' + 'When testing, code that causes React state updates should be wrapped into act(...):\n\n' + 'act(() => {\n' + ' /* fire events that update state */\n' + '});\n' + '/* assert on the output */\n\n' + "This ensures that you're testing the behavior the user would see in the browser." + ' Learn more at https://fb.me/react-wrap-tests-with-act' + '%s', getComponentName(fiber.type), getStackByFiberInDevAndProd(fiber));
|
|
19337
19669
|
}
|
|
19338
19670
|
}
|
|
19339
19671
|
}
|
|
@@ -19380,13 +19712,9 @@ function scheduleWork(fiber, expirationTime) {
|
|
|
19380
19712
|
}
|
|
19381
19713
|
|
|
19382
19714
|
function syncUpdates(fn, a, b, c, d) {
|
|
19383
|
-
|
|
19384
|
-
expirationContext = Sync;
|
|
19385
|
-
try {
|
|
19715
|
+
return scheduler.unstable_runWithPriority(scheduler.unstable_ImmediatePriority, function () {
|
|
19386
19716
|
return fn(a, b, c, d);
|
|
19387
|
-
}
|
|
19388
|
-
expirationContext = previousExpirationContext;
|
|
19389
|
-
}
|
|
19717
|
+
});
|
|
19390
19718
|
}
|
|
19391
19719
|
|
|
19392
19720
|
// TODO: Everything below this is written as if it has been lifted to the
|
|
@@ -19407,7 +19735,6 @@ var unhandledError = null;
|
|
|
19407
19735
|
|
|
19408
19736
|
var isBatchingUpdates = false;
|
|
19409
19737
|
var isUnbatchingUpdates = false;
|
|
19410
|
-
var isBatchingInteractiveUpdates = false;
|
|
19411
19738
|
|
|
19412
19739
|
var completedBatches = null;
|
|
19413
19740
|
|
|
@@ -19881,7 +20208,9 @@ function completeRoot(root, finishedWork, expirationTime) {
|
|
|
19881
20208
|
lastCommittedRootDuringThisBatch = root;
|
|
19882
20209
|
nestedUpdateCount = 0;
|
|
19883
20210
|
}
|
|
19884
|
-
|
|
20211
|
+
scheduler.unstable_runWithPriority(scheduler.unstable_ImmediatePriority, function () {
|
|
20212
|
+
commitRoot(root, finishedWork);
|
|
20213
|
+
});
|
|
19885
20214
|
}
|
|
19886
20215
|
|
|
19887
20216
|
function onUncaughtError(error) {
|
|
@@ -19939,9 +20268,6 @@ function flushSync(fn, a) {
|
|
|
19939
20268
|
}
|
|
19940
20269
|
|
|
19941
20270
|
function interactiveUpdates$1(fn, a, b) {
|
|
19942
|
-
if (isBatchingInteractiveUpdates) {
|
|
19943
|
-
return fn(a, b);
|
|
19944
|
-
}
|
|
19945
20271
|
// If there are any pending interactive updates, synchronously flush them.
|
|
19946
20272
|
// This needs to happen before we read any handlers, because the effect of
|
|
19947
20273
|
// the previous event may influence which handlers are called during
|
|
@@ -19951,14 +20277,13 @@ function interactiveUpdates$1(fn, a, b) {
|
|
|
19951
20277
|
performWork(lowestPriorityPendingInteractiveExpirationTime, false);
|
|
19952
20278
|
lowestPriorityPendingInteractiveExpirationTime = NoWork;
|
|
19953
20279
|
}
|
|
19954
|
-
var previousIsBatchingInteractiveUpdates = isBatchingInteractiveUpdates;
|
|
19955
20280
|
var previousIsBatchingUpdates = isBatchingUpdates;
|
|
19956
|
-
isBatchingInteractiveUpdates = true;
|
|
19957
20281
|
isBatchingUpdates = true;
|
|
19958
20282
|
try {
|
|
19959
|
-
return
|
|
20283
|
+
return scheduler.unstable_runWithPriority(scheduler.unstable_UserBlockingPriority, function () {
|
|
20284
|
+
return fn(a, b);
|
|
20285
|
+
});
|
|
19960
20286
|
} finally {
|
|
19961
|
-
isBatchingInteractiveUpdates = previousIsBatchingInteractiveUpdates;
|
|
19962
20287
|
isBatchingUpdates = previousIsBatchingUpdates;
|
|
19963
20288
|
if (!isBatchingUpdates && !isRendering) {
|
|
19964
20289
|
performSyncWork();
|
|
@@ -20221,7 +20546,7 @@ implementation) {
|
|
|
20221
20546
|
|
|
20222
20547
|
// TODO: this is special because it gets imported during build.
|
|
20223
20548
|
|
|
20224
|
-
var ReactVersion = '16.8.
|
|
20549
|
+
var ReactVersion = '16.8.2';
|
|
20225
20550
|
|
|
20226
20551
|
// TODO: This type is shared between the reconciler and ReactDOM, but will
|
|
20227
20552
|
// eventually be lifted out to the renderer.
|
|
@@ -20611,7 +20936,7 @@ var ReactDOM = {
|
|
|
20611
20936
|
hydrate: function (element, container, callback) {
|
|
20612
20937
|
!isValidContainer(container) ? invariant(false, 'Target container is not a DOM element.') : void 0;
|
|
20613
20938
|
{
|
|
20614
|
-
!!container._reactHasBeenPassedToCreateRootDEV ? warningWithoutStack$1(false, 'You are calling ReactDOM.hydrate() on a container that was previously ' + 'passed to ReactDOM.%s(). This is not supported. ' + 'Did you mean to call
|
|
20939
|
+
!!container._reactHasBeenPassedToCreateRootDEV ? warningWithoutStack$1(false, 'You are calling ReactDOM.hydrate() on a container that was previously ' + 'passed to ReactDOM.%s(). This is not supported. ' + 'Did you mean to call createRoot(container, {hydrate: true}).render(element)?', enableStableConcurrentModeAPIs ? 'createRoot' : 'unstable_createRoot') : void 0;
|
|
20615
20940
|
}
|
|
20616
20941
|
// TODO: throw or warn if we couldn't hydrate?
|
|
20617
20942
|
return legacyRenderSubtreeIntoContainer(null, element, container, true, callback);
|