react-dom 16.8.0 → 16.8.4

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.
Files changed (34) hide show
  1. package/build-info.json +5 -5
  2. package/cjs/react-dom-server.browser.development.js +74 -34
  3. package/cjs/react-dom-server.browser.production.min.js +35 -33
  4. package/cjs/react-dom-server.node.development.js +74 -34
  5. package/cjs/react-dom-server.node.production.min.js +36 -34
  6. package/cjs/react-dom-test-utils.development.js +23 -5
  7. package/cjs/react-dom-test-utils.production.min.js +23 -23
  8. package/cjs/react-dom-unstable-fire.development.js +698 -204
  9. package/cjs/react-dom-unstable-fire.production.min.js +252 -251
  10. package/cjs/react-dom-unstable-fire.profiling.min.js +179 -177
  11. package/cjs/react-dom-unstable-fizz.browser.development.js +1 -1
  12. package/cjs/react-dom-unstable-fizz.browser.production.min.js +1 -1
  13. package/cjs/react-dom-unstable-fizz.node.development.js +1 -1
  14. package/cjs/react-dom-unstable-fizz.node.production.min.js +1 -1
  15. package/cjs/react-dom-unstable-native-dependencies.development.js +2 -2
  16. package/cjs/react-dom-unstable-native-dependencies.production.min.js +1 -1
  17. package/cjs/react-dom.development.js +698 -204
  18. package/cjs/react-dom.production.min.js +252 -251
  19. package/cjs/react-dom.profiling.min.js +179 -177
  20. package/package.json +2 -2
  21. package/umd/react-dom-server.browser.development.js +74 -34
  22. package/umd/react-dom-server.browser.production.min.js +22 -21
  23. package/umd/react-dom-test-utils.development.js +23 -5
  24. package/umd/react-dom-test-utils.production.min.js +22 -21
  25. package/umd/react-dom-unstable-fire.development.js +706 -204
  26. package/umd/react-dom-unstable-fire.production.min.js +208 -207
  27. package/umd/react-dom-unstable-fire.profiling.min.js +208 -207
  28. package/umd/react-dom-unstable-fizz.browser.development.js +1 -1
  29. package/umd/react-dom-unstable-fizz.browser.production.min.js +1 -1
  30. package/umd/react-dom-unstable-native-dependencies.development.js +2 -2
  31. package/umd/react-dom-unstable-native-dependencies.production.min.js +1 -1
  32. package/umd/react-dom.development.js +706 -204
  33. package/umd/react-dom.production.min.js +208 -207
  34. package/umd/react-dom.profiling.min.js +208 -207
@@ -1,4 +1,4 @@
1
- /** @license React v16.8.0
1
+ /** @license React v16.8.4
2
2
  * react-dom.development.js
3
3
  *
4
4
  * Copyright (c) Facebook, Inc. and its affiliates.
@@ -79,7 +79,7 @@ var invokeGuardedCallbackImpl = function (name, func, context, a, b, c, d, e, f)
79
79
  // invokeGuardedCallback uses a try-catch, all user exceptions are treated
80
80
  // like caught exceptions, and the DevTools won't pause unless the developer
81
81
  // takes the extra step of enabling pause on caught exceptions. This is
82
- // untintuitive, though, because even though React has caught the error, from
82
+ // unintuitive, though, because even though React has caught the error, from
83
83
  // the developer's perspective, the error is uncaught.
84
84
  //
85
85
  // To preserve the expected "Pause on exceptions" behavior, we don't use a
@@ -836,6 +836,7 @@ var MemoComponent = 14;
836
836
  var SimpleMemoComponent = 15;
837
837
  var LazyComponent = 16;
838
838
  var IncompleteClassComponent = 17;
839
+ var DehydratedSuspenseComponent = 18;
839
840
 
840
841
  var randomKey = Math.random().toString(36).slice(2);
841
842
  var internalInstanceKey = '__reactInternalInstance$' + randomKey;
@@ -2382,6 +2383,15 @@ function updateValueIfChanged(node) {
2382
2383
 
2383
2384
  var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
2384
2385
 
2386
+ // Prevent newer renderers from RTE when used with older react package versions.
2387
+ // Current owner and dispatcher used to share the same ref,
2388
+ // but PR #14548 split them out to better support the react-debug-tools package.
2389
+ if (!ReactSharedInternals.hasOwnProperty('ReactCurrentDispatcher')) {
2390
+ ReactSharedInternals.ReactCurrentDispatcher = {
2391
+ current: null
2392
+ };
2393
+ }
2394
+
2385
2395
  var BEFORE_SLASH_RE = /^(.*)[\\\/]/;
2386
2396
 
2387
2397
  var describeComponentFrame = function (name, source, ownerName) {
@@ -2892,12 +2902,15 @@ var capitalize = function (token) {
2892
2902
  attributeName, 'http://www.w3.org/XML/1998/namespace');
2893
2903
  });
2894
2904
 
2895
- // Special case: this attribute exists both in HTML and SVG.
2896
- // Its "tabindex" attribute name is case-sensitive in SVG so we can't just use
2897
- // its React `tabIndex` name, like we do for attributes that exist only in HTML.
2898
- properties.tabIndex = new PropertyInfoRecord('tabIndex', STRING, false, // mustUseProperty
2899
- 'tabindex', // attributeName
2900
- null);
2905
+ // These attribute exists both in HTML and SVG.
2906
+ // The attribute name is case-sensitive in SVG so we can't just use
2907
+ // the React name like we do for attributes that exist only in HTML.
2908
+ ['tabIndex', 'crossOrigin'].forEach(function (attributeName) {
2909
+ properties[attributeName] = new PropertyInfoRecord(attributeName, STRING, false, // mustUseProperty
2910
+ attributeName.toLowerCase(), // attributeName
2911
+ null);
2912
+ } // attributeNamespace
2913
+ );
2901
2914
 
2902
2915
  /**
2903
2916
  * Get the value for a property on a node. Only used in DEV for SSR validation.
@@ -3241,7 +3254,7 @@ var enableProfilerTimer = true;
3241
3254
  var enableSchedulerTracing = true;
3242
3255
 
3243
3256
  // Only used in www builds.
3244
- // TODO: true? Here it might just be false.
3257
+ var enableSuspenseServerRenderer = false; // TODO: true? Here it might just be false.
3245
3258
 
3246
3259
  // Only used in www builds.
3247
3260
 
@@ -8701,8 +8714,16 @@ var unstable_now = _ReactInternals$Sched.unstable_now;
8701
8714
  var unstable_scheduleCallback = _ReactInternals$Sched.unstable_scheduleCallback;
8702
8715
  var unstable_shouldYield = _ReactInternals$Sched.unstable_shouldYield;
8703
8716
  var unstable_getFirstCallbackNode = _ReactInternals$Sched.unstable_getFirstCallbackNode;
8717
+ var unstable_runWithPriority = _ReactInternals$Sched.unstable_runWithPriority;
8718
+ var unstable_next = _ReactInternals$Sched.unstable_next;
8704
8719
  var unstable_continueExecution = _ReactInternals$Sched.unstable_continueExecution;
8705
8720
  var unstable_pauseExecution = _ReactInternals$Sched.unstable_pauseExecution;
8721
+ var unstable_getCurrentPriorityLevel = _ReactInternals$Sched.unstable_getCurrentPriorityLevel;
8722
+ var unstable_ImmediatePriority = _ReactInternals$Sched.unstable_ImmediatePriority;
8723
+ var unstable_UserBlockingPriority = _ReactInternals$Sched.unstable_UserBlockingPriority;
8724
+ var unstable_NormalPriority = _ReactInternals$Sched.unstable_NormalPriority;
8725
+ var unstable_LowPriority = _ReactInternals$Sched.unstable_LowPriority;
8726
+ var unstable_IdlePriority = _ReactInternals$Sched.unstable_IdlePriority;
8706
8727
 
8707
8728
  // Renderers that don't support persistence
8708
8729
  // can re-export everything from this module.
@@ -8727,6 +8748,9 @@ var SUPPRESS_HYDRATION_WARNING = void 0;
8727
8748
  SUPPRESS_HYDRATION_WARNING = 'suppressHydrationWarning';
8728
8749
  }
8729
8750
 
8751
+ var SUSPENSE_START_DATA = '$';
8752
+ var SUSPENSE_END_DATA = '/$';
8753
+
8730
8754
  var STYLE = 'style';
8731
8755
 
8732
8756
  var eventsEnabled = null;
@@ -8955,6 +8979,43 @@ function removeChildFromContainer(container, child) {
8955
8979
  }
8956
8980
  }
8957
8981
 
8982
+ function clearSuspenseBoundary(parentInstance, suspenseInstance) {
8983
+ var node = suspenseInstance;
8984
+ // Delete all nodes within this suspense boundary.
8985
+ // There might be nested nodes so we need to keep track of how
8986
+ // deep we are and only break out when we're back on top.
8987
+ var depth = 0;
8988
+ do {
8989
+ var nextNode = node.nextSibling;
8990
+ parentInstance.removeChild(node);
8991
+ if (nextNode && nextNode.nodeType === COMMENT_NODE) {
8992
+ var data = nextNode.data;
8993
+ if (data === SUSPENSE_END_DATA) {
8994
+ if (depth === 0) {
8995
+ parentInstance.removeChild(nextNode);
8996
+ return;
8997
+ } else {
8998
+ depth--;
8999
+ }
9000
+ } else if (data === SUSPENSE_START_DATA) {
9001
+ depth++;
9002
+ }
9003
+ }
9004
+ node = nextNode;
9005
+ } while (node);
9006
+ // TODO: Warn, we didn't find the end comment boundary.
9007
+ }
9008
+
9009
+ function clearSuspenseBoundaryFromContainer(container, suspenseInstance) {
9010
+ if (container.nodeType === COMMENT_NODE) {
9011
+ clearSuspenseBoundary(container.parentNode, suspenseInstance);
9012
+ } else if (container.nodeType === ELEMENT_NODE) {
9013
+ clearSuspenseBoundary(container, suspenseInstance);
9014
+ } else {
9015
+ // Document nodes should never contain suspense boundaries.
9016
+ }
9017
+ }
9018
+
8958
9019
  function hideInstance(instance) {
8959
9020
  // TODO: Does this work for all element types? What about MathML? Should we
8960
9021
  // pass host context to this method?
@@ -9000,10 +9061,19 @@ function canHydrateTextInstance(instance, text) {
9000
9061
  return instance;
9001
9062
  }
9002
9063
 
9064
+ function canHydrateSuspenseInstance(instance) {
9065
+ if (instance.nodeType !== COMMENT_NODE) {
9066
+ // Empty strings are not parsed by HTML so there won't be a correct match here.
9067
+ return null;
9068
+ }
9069
+ // This has now been refined to a suspense node.
9070
+ return instance;
9071
+ }
9072
+
9003
9073
  function getNextHydratableSibling(instance) {
9004
9074
  var node = instance.nextSibling;
9005
9075
  // Skip non-hydratable nodes.
9006
- while (node && node.nodeType !== ELEMENT_NODE && node.nodeType !== TEXT_NODE) {
9076
+ while (node && node.nodeType !== ELEMENT_NODE && node.nodeType !== TEXT_NODE && (!enableSuspenseServerRenderer || node.nodeType !== COMMENT_NODE || node.data !== SUSPENSE_START_DATA)) {
9007
9077
  node = node.nextSibling;
9008
9078
  }
9009
9079
  return node;
@@ -9012,7 +9082,7 @@ function getNextHydratableSibling(instance) {
9012
9082
  function getFirstHydratableChild(parentInstance) {
9013
9083
  var next = parentInstance.firstChild;
9014
9084
  // Skip non-hydratable nodes.
9015
- while (next && next.nodeType !== ELEMENT_NODE && next.nodeType !== TEXT_NODE) {
9085
+ while (next && next.nodeType !== ELEMENT_NODE && next.nodeType !== TEXT_NODE && (!enableSuspenseServerRenderer || next.nodeType !== COMMENT_NODE || next.data !== SUSPENSE_START_DATA)) {
9016
9086
  next = next.nextSibling;
9017
9087
  }
9018
9088
  return next;
@@ -9036,6 +9106,31 @@ function hydrateTextInstance(textInstance, text, internalInstanceHandle) {
9036
9106
  return diffHydratedText(textInstance, text);
9037
9107
  }
9038
9108
 
9109
+ function getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance) {
9110
+ var node = suspenseInstance.nextSibling;
9111
+ // Skip past all nodes within this suspense boundary.
9112
+ // There might be nested nodes so we need to keep track of how
9113
+ // deep we are and only break out when we're back on top.
9114
+ var depth = 0;
9115
+ while (node) {
9116
+ if (node.nodeType === COMMENT_NODE) {
9117
+ var data = node.data;
9118
+ if (data === SUSPENSE_END_DATA) {
9119
+ if (depth === 0) {
9120
+ return getNextHydratableSibling(node);
9121
+ } else {
9122
+ depth--;
9123
+ }
9124
+ } else if (data === SUSPENSE_START_DATA) {
9125
+ depth++;
9126
+ }
9127
+ }
9128
+ node = node.nextSibling;
9129
+ }
9130
+ // TODO: Warn, we didn't find the end comment boundary.
9131
+ return null;
9132
+ }
9133
+
9039
9134
  function didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, text) {
9040
9135
  {
9041
9136
  warnForUnmatchedText(textInstance, text);
@@ -9052,6 +9147,8 @@ function didNotHydrateContainerInstance(parentContainer, instance) {
9052
9147
  {
9053
9148
  if (instance.nodeType === ELEMENT_NODE) {
9054
9149
  warnForDeletedHydratableElement(parentContainer, instance);
9150
+ } else if (instance.nodeType === COMMENT_NODE) {
9151
+ // TODO: warnForDeletedHydratableSuspenseBoundary
9055
9152
  } else {
9056
9153
  warnForDeletedHydratableText(parentContainer, instance);
9057
9154
  }
@@ -9062,6 +9159,8 @@ function didNotHydrateInstance(parentType, parentProps, parentInstance, instance
9062
9159
  if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
9063
9160
  if (instance.nodeType === ELEMENT_NODE) {
9064
9161
  warnForDeletedHydratableElement(parentInstance, instance);
9162
+ } else if (instance.nodeType === COMMENT_NODE) {
9163
+ // TODO: warnForDeletedHydratableSuspenseBoundary
9065
9164
  } else {
9066
9165
  warnForDeletedHydratableText(parentInstance, instance);
9067
9166
  }
@@ -9080,6 +9179,8 @@ function didNotFindHydratableContainerTextInstance(parentContainer, text) {
9080
9179
  }
9081
9180
  }
9082
9181
 
9182
+
9183
+
9083
9184
  function didNotFindHydratableInstance(parentType, parentProps, parentInstance, type, props) {
9084
9185
  if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
9085
9186
  warnForInsertedHydratedElement(parentInstance, type, props);
@@ -9092,6 +9193,12 @@ function didNotFindHydratableTextInstance(parentType, parentProps, parentInstanc
9092
9193
  }
9093
9194
  }
9094
9195
 
9196
+ function didNotFindHydratableSuspenseInstance(parentType, parentProps, parentInstance) {
9197
+ if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
9198
+ // TODO: warnForInsertedHydratedSuspense(parentInstance);
9199
+ }
9200
+ }
9201
+
9095
9202
  // Prefix measurements so that it's possible to filter them.
9096
9203
  // Longer prefixes are hard to read in DevTools.
9097
9204
  var reactEmoji = '\u269B';
@@ -9347,7 +9454,7 @@ function stopFailedWorkTimer(fiber) {
9347
9454
  return;
9348
9455
  }
9349
9456
  fiber._debugIsCurrentlyTiming = false;
9350
- var warning = fiber.tag === SuspenseComponent ? 'Rendering was suspended' : 'An error was thrown inside this error boundary';
9457
+ var warning = fiber.tag === SuspenseComponent || fiber.tag === DehydratedSuspenseComponent ? 'Rendering was suspended' : 'An error was thrown inside this error boundary';
9351
9458
  endFiberMark(fiber, null, warning);
9352
9459
  }
9353
9460
  }
@@ -10016,6 +10123,7 @@ function FiberNode(tag, pendingProps, key, mode) {
10016
10123
  this._debugSource = null;
10017
10124
  this._debugOwner = null;
10018
10125
  this._debugIsCurrentlyTiming = false;
10126
+ this._debugHookTypes = null;
10019
10127
  if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') {
10020
10128
  Object.preventExtensions(this);
10021
10129
  }
@@ -10083,6 +10191,7 @@ function createWorkInProgress(current, pendingProps, expirationTime) {
10083
10191
  workInProgress._debugID = current._debugID;
10084
10192
  workInProgress._debugSource = current._debugSource;
10085
10193
  workInProgress._debugOwner = current._debugOwner;
10194
+ workInProgress._debugHookTypes = current._debugHookTypes;
10086
10195
  }
10087
10196
 
10088
10197
  workInProgress.alternate = current;
@@ -10350,6 +10459,7 @@ function assignFiberPropertiesInDEV(target, source) {
10350
10459
  target._debugSource = source._debugSource;
10351
10460
  target._debugOwner = source._debugOwner;
10352
10461
  target._debugIsCurrentlyTiming = source._debugIsCurrentlyTiming;
10462
+ target._debugHookTypes = source._debugHookTypes;
10353
10463
  return target;
10354
10464
  }
10355
10465
 
@@ -12167,7 +12277,7 @@ function ChildReconciler(shouldTrackSideEffects) {
12167
12277
  }
12168
12278
 
12169
12279
  function reconcileChildrenArray(returnFiber, currentFirstChild, newChildren, expirationTime) {
12170
- // This algorithm can't optimize by searching from boths ends since we
12280
+ // This algorithm can't optimize by searching from both ends since we
12171
12281
  // don't have backpointers on fibers. I'm trying to see how far we can get
12172
12282
  // with that model. If it ends up not being worth the tradeoffs, we can
12173
12283
  // add it later.
@@ -12748,7 +12858,6 @@ var currentlyRenderingFiber$1 = null;
12748
12858
  // current hook list is the list that belongs to the current fiber. The
12749
12859
  // work-in-progress hook list is a new list that will be added to the
12750
12860
  // work-in-progress fiber.
12751
- var firstCurrentHook = null;
12752
12861
  var currentHook = null;
12753
12862
  var nextCurrentHook = null;
12754
12863
  var firstWorkInProgressHook = null;
@@ -12778,39 +12887,67 @@ var RE_RENDER_LIMIT = 25;
12778
12887
  // In DEV, this is the name of the currently executing primitive hook
12779
12888
  var currentHookNameInDev = null;
12780
12889
 
12781
- function warnOnHookMismatchInDev() {
12890
+ // In DEV, this list ensures that hooks are called in the same order between renders.
12891
+ // The list stores the order of hooks used during the initial render (mount).
12892
+ // Subsequent renders (updates) reference this list.
12893
+ var hookTypesDev = null;
12894
+ var hookTypesUpdateIndexDev = -1;
12895
+
12896
+ function mountHookTypesDev() {
12897
+ {
12898
+ var hookName = currentHookNameInDev;
12899
+
12900
+ if (hookTypesDev === null) {
12901
+ hookTypesDev = [hookName];
12902
+ } else {
12903
+ hookTypesDev.push(hookName);
12904
+ }
12905
+ }
12906
+ }
12907
+
12908
+ function updateHookTypesDev() {
12909
+ {
12910
+ var hookName = currentHookNameInDev;
12911
+
12912
+ if (hookTypesDev !== null) {
12913
+ hookTypesUpdateIndexDev++;
12914
+ if (hookTypesDev[hookTypesUpdateIndexDev] !== hookName) {
12915
+ warnOnHookMismatchInDev(hookName);
12916
+ }
12917
+ }
12918
+ }
12919
+ }
12920
+
12921
+ function warnOnHookMismatchInDev(currentHookName) {
12782
12922
  {
12783
12923
  var componentName = getComponentName(currentlyRenderingFiber$1.type);
12784
12924
  if (!didWarnAboutMismatchedHooksForComponent.has(componentName)) {
12785
12925
  didWarnAboutMismatchedHooksForComponent.add(componentName);
12786
12926
 
12787
- var secondColumnStart = 22;
12927
+ if (hookTypesDev !== null) {
12928
+ var table = '';
12788
12929
 
12789
- var table = '';
12790
- var prevHook = firstCurrentHook;
12791
- var nextHook = firstWorkInProgressHook;
12792
- var n = 1;
12793
- while (prevHook !== null && nextHook !== null) {
12794
- var oldHookName = prevHook._debugType;
12795
- var newHookName = nextHook._debugType;
12930
+ var secondColumnStart = 30;
12796
12931
 
12797
- var row = n + '. ' + oldHookName;
12932
+ for (var i = 0; i <= hookTypesUpdateIndexDev; i++) {
12933
+ var oldHookName = hookTypesDev[i];
12934
+ var newHookName = i === hookTypesUpdateIndexDev ? currentHookName : oldHookName;
12798
12935
 
12799
- // Extra space so second column lines up
12800
- // lol @ IE not supporting String#repeat
12801
- while (row.length < secondColumnStart) {
12802
- row += ' ';
12803
- }
12936
+ var row = i + 1 + '. ' + oldHookName;
12804
12937
 
12805
- row += newHookName + '\n';
12938
+ // Extra space so second column lines up
12939
+ // lol @ IE not supporting String#repeat
12940
+ while (row.length < secondColumnStart) {
12941
+ row += ' ';
12942
+ }
12806
12943
 
12807
- table += row;
12808
- prevHook = prevHook.next;
12809
- nextHook = nextHook.next;
12810
- n++;
12811
- }
12944
+ row += newHookName + '\n';
12812
12945
 
12813
- warning$1(false, 'React has detected a change in the order of Hooks called by %s. ' + 'This will lead to bugs and errors if not fixed. ' + 'For more information, read the Rules of Hooks: https://fb.me/rules-of-hooks\n\n' + ' Previous render Next render\n' + ' -------------------------------\n' + '%s' + ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n', componentName, table);
12946
+ table += row;
12947
+ }
12948
+
12949
+ warning$1(false, 'React has detected a change in the order of Hooks called by %s. ' + 'This will lead to bugs and errors if not fixed. ' + 'For more information, read the Rules of Hooks: https://fb.me/rules-of-hooks\n\n' + ' Previous render Next render\n' + ' ------------------------------------------------------\n' + '%s' + ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n', componentName, table);
12950
+ }
12814
12951
  }
12815
12952
  }
12816
12953
  }
@@ -12846,7 +12983,12 @@ function areHookInputsEqual(nextDeps, prevDeps) {
12846
12983
  function renderWithHooks(current, workInProgress, Component, props, refOrContext, nextRenderExpirationTime) {
12847
12984
  renderExpirationTime = nextRenderExpirationTime;
12848
12985
  currentlyRenderingFiber$1 = workInProgress;
12849
- firstCurrentHook = nextCurrentHook = current !== null ? current.memoizedState : null;
12986
+ nextCurrentHook = current !== null ? current.memoizedState : null;
12987
+
12988
+ {
12989
+ hookTypesDev = current !== null ? current._debugHookTypes : null;
12990
+ hookTypesUpdateIndexDev = -1;
12991
+ }
12850
12992
 
12851
12993
  // The following should have already been reset
12852
12994
  // currentHook = null;
@@ -12860,8 +13002,26 @@ function renderWithHooks(current, workInProgress, Component, props, refOrContext
12860
13002
  // numberOfReRenders = 0;
12861
13003
  // sideEffectTag = 0;
12862
13004
 
13005
+ // TODO Warn if no hooks are used at all during mount, then some are used during update.
13006
+ // Currently we will identify the update render as a mount because nextCurrentHook === null.
13007
+ // This is tricky because it's valid for certain types of components (e.g. React.lazy)
13008
+
13009
+ // Using nextCurrentHook to differentiate between mount/update only works if at least one stateful hook is used.
13010
+ // Non-stateful hooks (e.g. context) don't get added to memoizedState,
13011
+ // so nextCurrentHook would be null during updates and mounts.
12863
13012
  {
12864
- ReactCurrentDispatcher$1.current = nextCurrentHook === null ? HooksDispatcherOnMountInDEV : HooksDispatcherOnUpdateInDEV;
13013
+ if (nextCurrentHook !== null) {
13014
+ ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV;
13015
+ } else if (hookTypesDev !== null) {
13016
+ // This dispatcher handles an edge case where a component is updating,
13017
+ // but no stateful hooks have been used.
13018
+ // We want to match the production code behavior (which will use HooksDispatcherOnMount),
13019
+ // but with the extra DEV validation to ensure hooks ordering hasn't changed.
13020
+ // This dispatcher does that.
13021
+ ReactCurrentDispatcher$1.current = HooksDispatcherOnMountWithHookTypesInDEV;
13022
+ } else {
13023
+ ReactCurrentDispatcher$1.current = HooksDispatcherOnMountInDEV;
13024
+ }
12865
13025
  }
12866
13026
 
12867
13027
  var children = Component(props, refOrContext);
@@ -12872,13 +13032,18 @@ function renderWithHooks(current, workInProgress, Component, props, refOrContext
12872
13032
  numberOfReRenders += 1;
12873
13033
 
12874
13034
  // Start over from the beginning of the list
12875
- firstCurrentHook = nextCurrentHook = current !== null ? current.memoizedState : null;
13035
+ nextCurrentHook = current !== null ? current.memoizedState : null;
12876
13036
  nextWorkInProgressHook = firstWorkInProgressHook;
12877
13037
 
12878
13038
  currentHook = null;
12879
13039
  workInProgressHook = null;
12880
13040
  componentUpdateQueue = null;
12881
13041
 
13042
+ {
13043
+ // Also validate hook order for cascading updates.
13044
+ hookTypesUpdateIndexDev = -1;
13045
+ }
13046
+
12882
13047
  ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV;
12883
13048
 
12884
13049
  children = Component(props, refOrContext);
@@ -12888,10 +13053,6 @@ function renderWithHooks(current, workInProgress, Component, props, refOrContext
12888
13053
  numberOfReRenders = 0;
12889
13054
  }
12890
13055
 
12891
- {
12892
- currentHookNameInDev = null;
12893
- }
12894
-
12895
13056
  // We can assume the previous dispatcher is always this one, since we set it
12896
13057
  // at the beginning of the render phase and there's no re-entrancy.
12897
13058
  ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
@@ -12903,18 +13064,29 @@ function renderWithHooks(current, workInProgress, Component, props, refOrContext
12903
13064
  renderedWork.updateQueue = componentUpdateQueue;
12904
13065
  renderedWork.effectTag |= sideEffectTag;
12905
13066
 
13067
+ {
13068
+ renderedWork._debugHookTypes = hookTypesDev;
13069
+ }
13070
+
13071
+ // This check uses currentHook so that it works the same in DEV and prod bundles.
13072
+ // hookTypesDev could catch more cases (e.g. context) but only in DEV bundles.
12906
13073
  var didRenderTooFewHooks = currentHook !== null && currentHook.next !== null;
12907
13074
 
12908
13075
  renderExpirationTime = NoWork;
12909
13076
  currentlyRenderingFiber$1 = null;
12910
13077
 
12911
- firstCurrentHook = null;
12912
13078
  currentHook = null;
12913
13079
  nextCurrentHook = null;
12914
13080
  firstWorkInProgressHook = null;
12915
13081
  workInProgressHook = null;
12916
13082
  nextWorkInProgressHook = null;
12917
13083
 
13084
+ {
13085
+ currentHookNameInDev = null;
13086
+ hookTypesDev = null;
13087
+ hookTypesUpdateIndexDev = -1;
13088
+ }
13089
+
12918
13090
  remainingExpirationTime = NoWork;
12919
13091
  componentUpdateQueue = null;
12920
13092
  sideEffectTag = 0;
@@ -12948,21 +13120,23 @@ function resetHooks() {
12948
13120
  renderExpirationTime = NoWork;
12949
13121
  currentlyRenderingFiber$1 = null;
12950
13122
 
12951
- firstCurrentHook = null;
12952
13123
  currentHook = null;
12953
13124
  nextCurrentHook = null;
12954
13125
  firstWorkInProgressHook = null;
12955
13126
  workInProgressHook = null;
12956
13127
  nextWorkInProgressHook = null;
12957
13128
 
12958
- remainingExpirationTime = NoWork;
12959
- componentUpdateQueue = null;
12960
- sideEffectTag = 0;
12961
-
12962
13129
  {
13130
+ hookTypesDev = null;
13131
+ hookTypesUpdateIndexDev = -1;
13132
+
12963
13133
  currentHookNameInDev = null;
12964
13134
  }
12965
13135
 
13136
+ remainingExpirationTime = NoWork;
13137
+ componentUpdateQueue = null;
13138
+ sideEffectTag = 0;
13139
+
12966
13140
  didScheduleRenderPhaseUpdate = false;
12967
13141
  renderPhaseUpdates = null;
12968
13142
  numberOfReRenders = 0;
@@ -12979,12 +13153,6 @@ function mountWorkInProgressHook() {
12979
13153
  next: null
12980
13154
  };
12981
13155
 
12982
- {
12983
- hook._debugType = currentHookNameInDev;
12984
- if (currentlyRenderingFiber$1 !== null && currentlyRenderingFiber$1.alternate !== null) {
12985
- 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));
12986
- }
12987
- }
12988
13156
  if (workInProgressHook === null) {
12989
13157
  // This is the first hook in the list
12990
13158
  firstWorkInProgressHook = workInProgressHook = hook;
@@ -13031,13 +13199,6 @@ function updateWorkInProgressHook() {
13031
13199
  workInProgressHook = workInProgressHook.next = newHook;
13032
13200
  }
13033
13201
  nextCurrentHook = currentHook.next;
13034
-
13035
- {
13036
- newHook._debugType = currentHookNameInDev;
13037
- if (currentHookNameInDev !== currentHook._debugType) {
13038
- warnOnHookMismatchInDev();
13039
- }
13040
- }
13041
13202
  }
13042
13203
  return workInProgressHook;
13043
13204
  }
@@ -13052,20 +13213,6 @@ function basicStateReducer(state, action) {
13052
13213
  return typeof action === 'function' ? action(state) : action;
13053
13214
  }
13054
13215
 
13055
- function mountContext(context, observedBits) {
13056
- {
13057
- mountWorkInProgressHook();
13058
- }
13059
- return readContext(context, observedBits);
13060
- }
13061
-
13062
- function updateContext(context, observedBits) {
13063
- {
13064
- updateWorkInProgressHook();
13065
- }
13066
- return readContext(context, observedBits);
13067
- }
13068
-
13069
13216
  function mountReducer(reducer, initialArg, init) {
13070
13217
  var hook = mountWorkInProgressHook();
13071
13218
  var initialState = void 0;
@@ -13118,7 +13265,6 @@ function updateReducer(reducer, initialArg, init) {
13118
13265
  }
13119
13266
 
13120
13267
  hook.memoizedState = newState;
13121
-
13122
13268
  // Don't persist the state accumlated from the render phase updates to
13123
13269
  // the base state unless the queue is empty.
13124
13270
  // TODO: Not sure if this is the desired semantics, but it's what we
@@ -13127,6 +13273,9 @@ function updateReducer(reducer, initialArg, init) {
13127
13273
  hook.baseState = newState;
13128
13274
  }
13129
13275
 
13276
+ queue.eagerReducer = reducer;
13277
+ queue.eagerState = newState;
13278
+
13130
13279
  return [newState, _dispatch];
13131
13280
  }
13132
13281
  }
@@ -13346,7 +13495,7 @@ function mountImperativeHandle(ref, create, deps) {
13346
13495
  }
13347
13496
 
13348
13497
  // TODO: If deps are provided, should we skip comparing the ref itself?
13349
- var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : [ref];
13498
+ var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
13350
13499
 
13351
13500
  return mountEffectImpl(Update, UnmountMutation | MountLayout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
13352
13501
  }
@@ -13357,7 +13506,7 @@ function updateImperativeHandle(ref, create, deps) {
13357
13506
  }
13358
13507
 
13359
13508
  // TODO: If deps are provided, should we skip comparing the ref itself?
13360
- var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : [ref];
13509
+ var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
13361
13510
 
13362
13511
  return updateEffectImpl(Update, UnmountMutation | MountLayout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
13363
13512
  }
@@ -13424,7 +13573,7 @@ function updateMemo(nextCreate, deps) {
13424
13573
  var shouldWarnForUnbatchedSetState = false;
13425
13574
 
13426
13575
  {
13427
- // jest isnt' a 'global', it's just exposed to tests via a wrapped function
13576
+ // jest isn't a 'global', it's just exposed to tests via a wrapped function
13428
13577
  // further, this isn't a test file, so flow doesn't recognize the symbol. So...
13429
13578
  // $FlowExpectedError - because requirements don't give a damn about your type sigs.
13430
13579
  if ('undefined' !== typeof jest) {
@@ -13556,6 +13705,7 @@ var ContextOnlyDispatcher = {
13556
13705
  };
13557
13706
 
13558
13707
  var HooksDispatcherOnMountInDEV = null;
13708
+ var HooksDispatcherOnMountWithHookTypesInDEV = null;
13559
13709
  var HooksDispatcherOnUpdateInDEV = null;
13560
13710
  var InvalidNestedHooksDispatcherOnMountInDEV = null;
13561
13711
  var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
@@ -13575,26 +13725,32 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
13575
13725
  },
13576
13726
  useCallback: function (callback, deps) {
13577
13727
  currentHookNameInDev = 'useCallback';
13728
+ mountHookTypesDev();
13578
13729
  return mountCallback(callback, deps);
13579
13730
  },
13580
13731
  useContext: function (context, observedBits) {
13581
13732
  currentHookNameInDev = 'useContext';
13582
- return mountContext(context, observedBits);
13733
+ mountHookTypesDev();
13734
+ return readContext(context, observedBits);
13583
13735
  },
13584
13736
  useEffect: function (create, deps) {
13585
13737
  currentHookNameInDev = 'useEffect';
13738
+ mountHookTypesDev();
13586
13739
  return mountEffect(create, deps);
13587
13740
  },
13588
13741
  useImperativeHandle: function (ref, create, deps) {
13589
13742
  currentHookNameInDev = 'useImperativeHandle';
13743
+ mountHookTypesDev();
13590
13744
  return mountImperativeHandle(ref, create, deps);
13591
13745
  },
13592
13746
  useLayoutEffect: function (create, deps) {
13593
13747
  currentHookNameInDev = 'useLayoutEffect';
13748
+ mountHookTypesDev();
13594
13749
  return mountLayoutEffect(create, deps);
13595
13750
  },
13596
13751
  useMemo: function (create, deps) {
13597
13752
  currentHookNameInDev = 'useMemo';
13753
+ mountHookTypesDev();
13598
13754
  var prevDispatcher = ReactCurrentDispatcher$1.current;
13599
13755
  ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
13600
13756
  try {
@@ -13605,6 +13761,7 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
13605
13761
  },
13606
13762
  useReducer: function (reducer, initialArg, init) {
13607
13763
  currentHookNameInDev = 'useReducer';
13764
+ mountHookTypesDev();
13608
13765
  var prevDispatcher = ReactCurrentDispatcher$1.current;
13609
13766
  ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
13610
13767
  try {
@@ -13615,10 +13772,12 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
13615
13772
  },
13616
13773
  useRef: function (initialValue) {
13617
13774
  currentHookNameInDev = 'useRef';
13775
+ mountHookTypesDev();
13618
13776
  return mountRef(initialValue);
13619
13777
  },
13620
13778
  useState: function (initialState) {
13621
13779
  currentHookNameInDev = 'useState';
13780
+ mountHookTypesDev();
13622
13781
  var prevDispatcher = ReactCurrentDispatcher$1.current;
13623
13782
  ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
13624
13783
  try {
@@ -13629,6 +13788,81 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
13629
13788
  },
13630
13789
  useDebugValue: function (value, formatterFn) {
13631
13790
  currentHookNameInDev = 'useDebugValue';
13791
+ mountHookTypesDev();
13792
+ return mountDebugValue(value, formatterFn);
13793
+ }
13794
+ };
13795
+
13796
+ HooksDispatcherOnMountWithHookTypesInDEV = {
13797
+ readContext: function (context, observedBits) {
13798
+ return readContext(context, observedBits);
13799
+ },
13800
+ useCallback: function (callback, deps) {
13801
+ currentHookNameInDev = 'useCallback';
13802
+ updateHookTypesDev();
13803
+ return mountCallback(callback, deps);
13804
+ },
13805
+ useContext: function (context, observedBits) {
13806
+ currentHookNameInDev = 'useContext';
13807
+ updateHookTypesDev();
13808
+ return readContext(context, observedBits);
13809
+ },
13810
+ useEffect: function (create, deps) {
13811
+ currentHookNameInDev = 'useEffect';
13812
+ updateHookTypesDev();
13813
+ return mountEffect(create, deps);
13814
+ },
13815
+ useImperativeHandle: function (ref, create, deps) {
13816
+ currentHookNameInDev = 'useImperativeHandle';
13817
+ updateHookTypesDev();
13818
+ return mountImperativeHandle(ref, create, deps);
13819
+ },
13820
+ useLayoutEffect: function (create, deps) {
13821
+ currentHookNameInDev = 'useLayoutEffect';
13822
+ updateHookTypesDev();
13823
+ return mountLayoutEffect(create, deps);
13824
+ },
13825
+ useMemo: function (create, deps) {
13826
+ currentHookNameInDev = 'useMemo';
13827
+ updateHookTypesDev();
13828
+ var prevDispatcher = ReactCurrentDispatcher$1.current;
13829
+ ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
13830
+ try {
13831
+ return mountMemo(create, deps);
13832
+ } finally {
13833
+ ReactCurrentDispatcher$1.current = prevDispatcher;
13834
+ }
13835
+ },
13836
+ useReducer: function (reducer, initialArg, init) {
13837
+ currentHookNameInDev = 'useReducer';
13838
+ updateHookTypesDev();
13839
+ var prevDispatcher = ReactCurrentDispatcher$1.current;
13840
+ ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
13841
+ try {
13842
+ return mountReducer(reducer, initialArg, init);
13843
+ } finally {
13844
+ ReactCurrentDispatcher$1.current = prevDispatcher;
13845
+ }
13846
+ },
13847
+ useRef: function (initialValue) {
13848
+ currentHookNameInDev = 'useRef';
13849
+ updateHookTypesDev();
13850
+ return mountRef(initialValue);
13851
+ },
13852
+ useState: function (initialState) {
13853
+ currentHookNameInDev = 'useState';
13854
+ updateHookTypesDev();
13855
+ var prevDispatcher = ReactCurrentDispatcher$1.current;
13856
+ ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
13857
+ try {
13858
+ return mountState(initialState);
13859
+ } finally {
13860
+ ReactCurrentDispatcher$1.current = prevDispatcher;
13861
+ }
13862
+ },
13863
+ useDebugValue: function (value, formatterFn) {
13864
+ currentHookNameInDev = 'useDebugValue';
13865
+ updateHookTypesDev();
13632
13866
  return mountDebugValue(value, formatterFn);
13633
13867
  }
13634
13868
  };
@@ -13639,26 +13873,32 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
13639
13873
  },
13640
13874
  useCallback: function (callback, deps) {
13641
13875
  currentHookNameInDev = 'useCallback';
13876
+ updateHookTypesDev();
13642
13877
  return updateCallback(callback, deps);
13643
13878
  },
13644
13879
  useContext: function (context, observedBits) {
13645
13880
  currentHookNameInDev = 'useContext';
13646
- return updateContext(context, observedBits);
13881
+ updateHookTypesDev();
13882
+ return readContext(context, observedBits);
13647
13883
  },
13648
13884
  useEffect: function (create, deps) {
13649
13885
  currentHookNameInDev = 'useEffect';
13886
+ updateHookTypesDev();
13650
13887
  return updateEffect(create, deps);
13651
13888
  },
13652
13889
  useImperativeHandle: function (ref, create, deps) {
13653
13890
  currentHookNameInDev = 'useImperativeHandle';
13891
+ updateHookTypesDev();
13654
13892
  return updateImperativeHandle(ref, create, deps);
13655
13893
  },
13656
13894
  useLayoutEffect: function (create, deps) {
13657
13895
  currentHookNameInDev = 'useLayoutEffect';
13896
+ updateHookTypesDev();
13658
13897
  return updateLayoutEffect(create, deps);
13659
13898
  },
13660
13899
  useMemo: function (create, deps) {
13661
13900
  currentHookNameInDev = 'useMemo';
13901
+ updateHookTypesDev();
13662
13902
  var prevDispatcher = ReactCurrentDispatcher$1.current;
13663
13903
  ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
13664
13904
  try {
@@ -13669,6 +13909,7 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
13669
13909
  },
13670
13910
  useReducer: function (reducer, initialArg, init) {
13671
13911
  currentHookNameInDev = 'useReducer';
13912
+ updateHookTypesDev();
13672
13913
  var prevDispatcher = ReactCurrentDispatcher$1.current;
13673
13914
  ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
13674
13915
  try {
@@ -13679,10 +13920,12 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
13679
13920
  },
13680
13921
  useRef: function (initialValue) {
13681
13922
  currentHookNameInDev = 'useRef';
13923
+ updateHookTypesDev();
13682
13924
  return updateRef(initialValue);
13683
13925
  },
13684
13926
  useState: function (initialState) {
13685
13927
  currentHookNameInDev = 'useState';
13928
+ updateHookTypesDev();
13686
13929
  var prevDispatcher = ReactCurrentDispatcher$1.current;
13687
13930
  ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
13688
13931
  try {
@@ -13693,6 +13936,7 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
13693
13936
  },
13694
13937
  useDebugValue: function (value, formatterFn) {
13695
13938
  currentHookNameInDev = 'useDebugValue';
13939
+ updateHookTypesDev();
13696
13940
  return updateDebugValue(value, formatterFn);
13697
13941
  }
13698
13942
  };
@@ -13705,31 +13949,37 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
13705
13949
  useCallback: function (callback, deps) {
13706
13950
  currentHookNameInDev = 'useCallback';
13707
13951
  warnInvalidHookAccess();
13952
+ mountHookTypesDev();
13708
13953
  return mountCallback(callback, deps);
13709
13954
  },
13710
13955
  useContext: function (context, observedBits) {
13711
13956
  currentHookNameInDev = 'useContext';
13712
13957
  warnInvalidHookAccess();
13713
- return mountContext(context, observedBits);
13958
+ mountHookTypesDev();
13959
+ return readContext(context, observedBits);
13714
13960
  },
13715
13961
  useEffect: function (create, deps) {
13716
13962
  currentHookNameInDev = 'useEffect';
13717
13963
  warnInvalidHookAccess();
13964
+ mountHookTypesDev();
13718
13965
  return mountEffect(create, deps);
13719
13966
  },
13720
13967
  useImperativeHandle: function (ref, create, deps) {
13721
13968
  currentHookNameInDev = 'useImperativeHandle';
13722
13969
  warnInvalidHookAccess();
13970
+ mountHookTypesDev();
13723
13971
  return mountImperativeHandle(ref, create, deps);
13724
13972
  },
13725
13973
  useLayoutEffect: function (create, deps) {
13726
13974
  currentHookNameInDev = 'useLayoutEffect';
13727
13975
  warnInvalidHookAccess();
13976
+ mountHookTypesDev();
13728
13977
  return mountLayoutEffect(create, deps);
13729
13978
  },
13730
13979
  useMemo: function (create, deps) {
13731
13980
  currentHookNameInDev = 'useMemo';
13732
13981
  warnInvalidHookAccess();
13982
+ mountHookTypesDev();
13733
13983
  var prevDispatcher = ReactCurrentDispatcher$1.current;
13734
13984
  ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
13735
13985
  try {
@@ -13741,6 +13991,7 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
13741
13991
  useReducer: function (reducer, initialArg, init) {
13742
13992
  currentHookNameInDev = 'useReducer';
13743
13993
  warnInvalidHookAccess();
13994
+ mountHookTypesDev();
13744
13995
  var prevDispatcher = ReactCurrentDispatcher$1.current;
13745
13996
  ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
13746
13997
  try {
@@ -13752,11 +14003,13 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
13752
14003
  useRef: function (initialValue) {
13753
14004
  currentHookNameInDev = 'useRef';
13754
14005
  warnInvalidHookAccess();
14006
+ mountHookTypesDev();
13755
14007
  return mountRef(initialValue);
13756
14008
  },
13757
14009
  useState: function (initialState) {
13758
14010
  currentHookNameInDev = 'useState';
13759
14011
  warnInvalidHookAccess();
14012
+ mountHookTypesDev();
13760
14013
  var prevDispatcher = ReactCurrentDispatcher$1.current;
13761
14014
  ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
13762
14015
  try {
@@ -13768,6 +14021,7 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
13768
14021
  useDebugValue: function (value, formatterFn) {
13769
14022
  currentHookNameInDev = 'useDebugValue';
13770
14023
  warnInvalidHookAccess();
14024
+ mountHookTypesDev();
13771
14025
  return mountDebugValue(value, formatterFn);
13772
14026
  }
13773
14027
  };
@@ -13780,31 +14034,37 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
13780
14034
  useCallback: function (callback, deps) {
13781
14035
  currentHookNameInDev = 'useCallback';
13782
14036
  warnInvalidHookAccess();
14037
+ updateHookTypesDev();
13783
14038
  return updateCallback(callback, deps);
13784
14039
  },
13785
14040
  useContext: function (context, observedBits) {
13786
14041
  currentHookNameInDev = 'useContext';
13787
14042
  warnInvalidHookAccess();
13788
- return updateContext(context, observedBits);
14043
+ updateHookTypesDev();
14044
+ return readContext(context, observedBits);
13789
14045
  },
13790
14046
  useEffect: function (create, deps) {
13791
14047
  currentHookNameInDev = 'useEffect';
13792
14048
  warnInvalidHookAccess();
14049
+ updateHookTypesDev();
13793
14050
  return updateEffect(create, deps);
13794
14051
  },
13795
14052
  useImperativeHandle: function (ref, create, deps) {
13796
14053
  currentHookNameInDev = 'useImperativeHandle';
13797
14054
  warnInvalidHookAccess();
14055
+ updateHookTypesDev();
13798
14056
  return updateImperativeHandle(ref, create, deps);
13799
14057
  },
13800
14058
  useLayoutEffect: function (create, deps) {
13801
14059
  currentHookNameInDev = 'useLayoutEffect';
13802
14060
  warnInvalidHookAccess();
14061
+ updateHookTypesDev();
13803
14062
  return updateLayoutEffect(create, deps);
13804
14063
  },
13805
14064
  useMemo: function (create, deps) {
13806
14065
  currentHookNameInDev = 'useMemo';
13807
14066
  warnInvalidHookAccess();
14067
+ updateHookTypesDev();
13808
14068
  var prevDispatcher = ReactCurrentDispatcher$1.current;
13809
14069
  ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
13810
14070
  try {
@@ -13816,6 +14076,7 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
13816
14076
  useReducer: function (reducer, initialArg, init) {
13817
14077
  currentHookNameInDev = 'useReducer';
13818
14078
  warnInvalidHookAccess();
14079
+ updateHookTypesDev();
13819
14080
  var prevDispatcher = ReactCurrentDispatcher$1.current;
13820
14081
  ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
13821
14082
  try {
@@ -13827,11 +14088,13 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
13827
14088
  useRef: function (initialValue) {
13828
14089
  currentHookNameInDev = 'useRef';
13829
14090
  warnInvalidHookAccess();
14091
+ updateHookTypesDev();
13830
14092
  return updateRef(initialValue);
13831
14093
  },
13832
14094
  useState: function (initialState) {
13833
14095
  currentHookNameInDev = 'useState';
13834
14096
  warnInvalidHookAccess();
14097
+ updateHookTypesDev();
13835
14098
  var prevDispatcher = ReactCurrentDispatcher$1.current;
13836
14099
  ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
13837
14100
  try {
@@ -13843,6 +14106,7 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
13843
14106
  useDebugValue: function (value, formatterFn) {
13844
14107
  currentHookNameInDev = 'useDebugValue';
13845
14108
  warnInvalidHookAccess();
14109
+ updateHookTypesDev();
13846
14110
  return updateDebugValue(value, formatterFn);
13847
14111
  }
13848
14112
  };
@@ -13914,6 +14178,18 @@ function enterHydrationState(fiber) {
13914
14178
  return true;
13915
14179
  }
13916
14180
 
14181
+ function reenterHydrationStateFromDehydratedSuspenseInstance(fiber) {
14182
+ if (!supportsHydration) {
14183
+ return false;
14184
+ }
14185
+
14186
+ var suspenseInstance = fiber.stateNode;
14187
+ nextHydratableInstance = getNextHydratableSibling(suspenseInstance);
14188
+ popToNextHostParent(fiber);
14189
+ isHydrating = true;
14190
+ return true;
14191
+ }
14192
+
13917
14193
  function deleteHydratableInstance(returnFiber, instance) {
13918
14194
  {
13919
14195
  switch (returnFiber.tag) {
@@ -13960,6 +14236,9 @@ function insertNonHydratedInstance(returnFiber, fiber) {
13960
14236
  case HostText:
13961
14237
  var text = fiber.pendingProps;
13962
14238
  didNotFindHydratableContainerTextInstance(parentContainer, text);
14239
+ break;
14240
+ case SuspenseComponent:
14241
+
13963
14242
  break;
13964
14243
  }
13965
14244
  break;
@@ -13979,6 +14258,9 @@ function insertNonHydratedInstance(returnFiber, fiber) {
13979
14258
  var _text = fiber.pendingProps;
13980
14259
  didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, _text);
13981
14260
  break;
14261
+ case SuspenseComponent:
14262
+ didNotFindHydratableSuspenseInstance(parentType, parentProps, parentInstance);
14263
+ break;
13982
14264
  }
13983
14265
  break;
13984
14266
  }
@@ -14011,6 +14293,19 @@ function tryHydrate(fiber, nextInstance) {
14011
14293
  }
14012
14294
  return false;
14013
14295
  }
14296
+ case SuspenseComponent:
14297
+ {
14298
+ if (enableSuspenseServerRenderer) {
14299
+ var suspenseInstance = canHydrateSuspenseInstance(nextInstance);
14300
+ if (suspenseInstance !== null) {
14301
+ // Downgrade the tag to a dehydrated component until we've hydrated it.
14302
+ fiber.tag = DehydratedSuspenseComponent;
14303
+ fiber.stateNode = suspenseInstance;
14304
+ return true;
14305
+ }
14306
+ }
14307
+ return false;
14308
+ }
14014
14309
  default:
14015
14310
  return false;
14016
14311
  }
@@ -14104,9 +14399,18 @@ function prepareToHydrateHostTextInstance(fiber) {
14104
14399
  return shouldUpdate;
14105
14400
  }
14106
14401
 
14402
+ function skipPastDehydratedSuspenseInstance(fiber) {
14403
+ if (!supportsHydration) {
14404
+ invariant(false, 'Expected skipPastDehydratedSuspenseInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.');
14405
+ }
14406
+ var suspenseInstance = fiber.stateNode;
14407
+ !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;
14408
+ nextHydratableInstance = getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance);
14409
+ }
14410
+
14107
14411
  function popToNextHostParent(fiber) {
14108
14412
  var parent = fiber.return;
14109
- while (parent !== null && parent.tag !== HostComponent && parent.tag !== HostRoot) {
14413
+ while (parent !== null && parent.tag !== HostComponent && parent.tag !== HostRoot && parent.tag !== DehydratedSuspenseComponent) {
14110
14414
  parent = parent.return;
14111
14415
  }
14112
14416
  hydrationParentFiber = parent;
@@ -14214,6 +14518,10 @@ function forceUnmountCurrentAndReconcile(current$$1, workInProgress, nextChildre
14214
14518
  }
14215
14519
 
14216
14520
  function updateForwardRef(current$$1, workInProgress, Component, nextProps, renderExpirationTime) {
14521
+ // TODO: current can be non-null here even if the component
14522
+ // hasn't yet mounted. This happens after the first render suspends.
14523
+ // We'll need to figure out if this is fine or can cause issues.
14524
+
14217
14525
  {
14218
14526
  if (workInProgress.type !== workInProgress.elementType) {
14219
14527
  // Lazy component props can't be validated in createElement
@@ -14319,6 +14627,10 @@ function updateMemoComponent(current$$1, workInProgress, Component, nextProps, u
14319
14627
  }
14320
14628
 
14321
14629
  function updateSimpleMemoComponent(current$$1, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
14630
+ // TODO: current can be non-null here even if the component
14631
+ // hasn't yet mounted. This happens when the inner render suspends.
14632
+ // We'll need to figure out if this is fine or can cause issues.
14633
+
14322
14634
  {
14323
14635
  if (workInProgress.type !== workInProgress.elementType) {
14324
14636
  // Lazy component props can't be validated in createElement
@@ -14942,6 +15254,18 @@ function updateSuspenseComponent(current$$1, workInProgress, renderExpirationTim
14942
15254
  // children -- we skip over the primary children entirely.
14943
15255
  var next = void 0;
14944
15256
  if (current$$1 === null) {
15257
+ if (enableSuspenseServerRenderer) {
15258
+ // If we're currently hydrating, try to hydrate this boundary.
15259
+ // But only if this has a fallback.
15260
+ if (nextProps.fallback !== undefined) {
15261
+ tryToClaimNextHydratableInstance(workInProgress);
15262
+ // This could've changed the tag if this was a dehydrated suspense component.
15263
+ if (workInProgress.tag === DehydratedSuspenseComponent) {
15264
+ return updateDehydratedSuspenseComponent(null, workInProgress, renderExpirationTime);
15265
+ }
15266
+ }
15267
+ }
15268
+
14945
15269
  // This is the initial mount. This branch is pretty simple because there's
14946
15270
  // no previous state that needs to be preserved.
14947
15271
  if (nextDidTimeout) {
@@ -15093,6 +15417,65 @@ function updateSuspenseComponent(current$$1, workInProgress, renderExpirationTim
15093
15417
  return next;
15094
15418
  }
15095
15419
 
15420
+ function updateDehydratedSuspenseComponent(current$$1, workInProgress, renderExpirationTime) {
15421
+ if (current$$1 === null) {
15422
+ // During the first pass, we'll bail out and not drill into the children.
15423
+ // Instead, we'll leave the content in place and try to hydrate it later.
15424
+ workInProgress.expirationTime = Never;
15425
+ return null;
15426
+ }
15427
+ // We use childExpirationTime to indicate that a child might depend on context, so if
15428
+ // any context has changed, we need to treat is as if the input might have changed.
15429
+ var hasContextChanged$$1 = current$$1.childExpirationTime >= renderExpirationTime;
15430
+ if (didReceiveUpdate || hasContextChanged$$1) {
15431
+ // This boundary has changed since the first render. This means that we are now unable to
15432
+ // hydrate it. We might still be able to hydrate it using an earlier expiration time but
15433
+ // during this render we can't. Instead, we're going to delete the whole subtree and
15434
+ // instead inject a new real Suspense boundary to take its place, which may render content
15435
+ // or fallback. The real Suspense boundary will suspend for a while so we have some time
15436
+ // to ensure it can produce real content, but all state and pending events will be lost.
15437
+
15438
+ // Detach from the current dehydrated boundary.
15439
+ current$$1.alternate = null;
15440
+ workInProgress.alternate = null;
15441
+
15442
+ // Insert a deletion in the effect list.
15443
+ var returnFiber = workInProgress.return;
15444
+ !(returnFiber !== null) ? invariant(false, 'Suspense boundaries are never on the root. This is probably a bug in React.') : void 0;
15445
+ var last = returnFiber.lastEffect;
15446
+ if (last !== null) {
15447
+ last.nextEffect = current$$1;
15448
+ returnFiber.lastEffect = current$$1;
15449
+ } else {
15450
+ returnFiber.firstEffect = returnFiber.lastEffect = current$$1;
15451
+ }
15452
+ current$$1.nextEffect = null;
15453
+ current$$1.effectTag = Deletion;
15454
+
15455
+ // Upgrade this work in progress to a real Suspense component.
15456
+ workInProgress.tag = SuspenseComponent;
15457
+ workInProgress.stateNode = null;
15458
+ workInProgress.memoizedState = null;
15459
+ // This is now an insertion.
15460
+ workInProgress.effectTag |= Placement;
15461
+ // Retry as a real Suspense component.
15462
+ return updateSuspenseComponent(null, workInProgress, renderExpirationTime);
15463
+ }
15464
+ if ((workInProgress.effectTag & DidCapture) === NoEffect) {
15465
+ // This is the first attempt.
15466
+ reenterHydrationStateFromDehydratedSuspenseInstance(workInProgress);
15467
+ var nextProps = workInProgress.pendingProps;
15468
+ var nextChildren = nextProps.children;
15469
+ workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
15470
+ return workInProgress.child;
15471
+ } else {
15472
+ // Something suspended. Leave the existing children in place.
15473
+ // TODO: In non-concurrent mode, should we commit the nodes we have hydrated so far?
15474
+ workInProgress.child = null;
15475
+ return null;
15476
+ }
15477
+ }
15478
+
15096
15479
  function updatePortalComponent(current$$1, workInProgress, renderExpirationTime) {
15097
15480
  pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
15098
15481
  var nextChildren = workInProgress.pendingProps;
@@ -15304,6 +15687,16 @@ function beginWork(current$$1, workInProgress, renderExpirationTime) {
15304
15687
  }
15305
15688
  break;
15306
15689
  }
15690
+ case DehydratedSuspenseComponent:
15691
+ {
15692
+ if (enableSuspenseServerRenderer) {
15693
+ // We know that this component will suspend again because if it has
15694
+ // been unsuspended it has committed as a regular Suspense component.
15695
+ // If it needs to be retried, it should have work scheduled on it.
15696
+ workInProgress.effectTag |= DidCapture;
15697
+ break;
15698
+ }
15699
+ }
15307
15700
  }
15308
15701
  return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
15309
15702
  }
@@ -15395,9 +15788,15 @@ function beginWork(current$$1, workInProgress, renderExpirationTime) {
15395
15788
  var _resolvedProps4 = workInProgress.elementType === _Component3 ? _unresolvedProps4 : resolveDefaultProps(_Component3, _unresolvedProps4);
15396
15789
  return mountIncompleteClassComponent(current$$1, workInProgress, _Component3, _resolvedProps4, renderExpirationTime);
15397
15790
  }
15398
- default:
15399
- invariant(false, 'Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.');
15791
+ case DehydratedSuspenseComponent:
15792
+ {
15793
+ if (enableSuspenseServerRenderer) {
15794
+ return updateDehydratedSuspenseComponent(current$$1, workInProgress, renderExpirationTime);
15795
+ }
15796
+ break;
15797
+ }
15400
15798
  }
15799
+ invariant(false, 'Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.');
15401
15800
  }
15402
15801
 
15403
15802
  var valueCursor = createCursor(null);
@@ -15486,6 +15885,28 @@ function calculateChangedBits(context, newValue, oldValue) {
15486
15885
  }
15487
15886
  }
15488
15887
 
15888
+ function scheduleWorkOnParentPath(parent, renderExpirationTime) {
15889
+ // Update the child expiration time of all the ancestors, including
15890
+ // the alternates.
15891
+ var node = parent;
15892
+ while (node !== null) {
15893
+ var alternate = node.alternate;
15894
+ if (node.childExpirationTime < renderExpirationTime) {
15895
+ node.childExpirationTime = renderExpirationTime;
15896
+ if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
15897
+ alternate.childExpirationTime = renderExpirationTime;
15898
+ }
15899
+ } else if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
15900
+ alternate.childExpirationTime = renderExpirationTime;
15901
+ } else {
15902
+ // Neither alternate was updated, which means the rest of the
15903
+ // ancestor path already has sufficient priority.
15904
+ break;
15905
+ }
15906
+ node = node.return;
15907
+ }
15908
+ }
15909
+
15489
15910
  function propagateContextChange(workInProgress, context, changedBits, renderExpirationTime) {
15490
15911
  var fiber = workInProgress.child;
15491
15912
  if (fiber !== null) {
@@ -15524,25 +15945,8 @@ function propagateContextChange(workInProgress, context, changedBits, renderExpi
15524
15945
  if (alternate !== null && alternate.expirationTime < renderExpirationTime) {
15525
15946
  alternate.expirationTime = renderExpirationTime;
15526
15947
  }
15527
- // Update the child expiration time of all the ancestors, including
15528
- // the alternates.
15529
- var node = fiber.return;
15530
- while (node !== null) {
15531
- alternate = node.alternate;
15532
- if (node.childExpirationTime < renderExpirationTime) {
15533
- node.childExpirationTime = renderExpirationTime;
15534
- if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
15535
- alternate.childExpirationTime = renderExpirationTime;
15536
- }
15537
- } else if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
15538
- alternate.childExpirationTime = renderExpirationTime;
15539
- } else {
15540
- // Neither alternate was updated, which means the rest of the
15541
- // ancestor path already has sufficient priority.
15542
- break;
15543
- }
15544
- node = node.return;
15545
- }
15948
+
15949
+ scheduleWorkOnParentPath(fiber.return, renderExpirationTime);
15546
15950
 
15547
15951
  // Mark the expiration time on the list, too.
15548
15952
  if (list.expirationTime < renderExpirationTime) {
@@ -15558,6 +15962,23 @@ function propagateContextChange(workInProgress, context, changedBits, renderExpi
15558
15962
  } else if (fiber.tag === ContextProvider) {
15559
15963
  // Don't scan deeper if this is a matching provider
15560
15964
  nextFiber = fiber.type === workInProgress.type ? null : fiber.child;
15965
+ } else if (enableSuspenseServerRenderer && fiber.tag === DehydratedSuspenseComponent) {
15966
+ // If a dehydrated suspense component is in this subtree, we don't know
15967
+ // if it will have any context consumers in it. The best we can do is
15968
+ // mark it as having updates on its children.
15969
+ if (fiber.expirationTime < renderExpirationTime) {
15970
+ fiber.expirationTime = renderExpirationTime;
15971
+ }
15972
+ var _alternate = fiber.alternate;
15973
+ if (_alternate !== null && _alternate.expirationTime < renderExpirationTime) {
15974
+ _alternate.expirationTime = renderExpirationTime;
15975
+ }
15976
+ // This is intentionally passing this fiber as the parent
15977
+ // because we want to schedule this fiber as having work
15978
+ // on its children. We'll use the childExpirationTime on
15979
+ // this fiber to indicate that a context has changed.
15980
+ scheduleWorkOnParentPath(fiber, renderExpirationTime);
15981
+ nextFiber = fiber.sibling;
15561
15982
  } else {
15562
15983
  // Traverse down.
15563
15984
  nextFiber = fiber.child;
@@ -16681,6 +17102,26 @@ function completeWork(current, workInProgress, renderExpirationTime) {
16681
17102
  }
16682
17103
  break;
16683
17104
  }
17105
+ case DehydratedSuspenseComponent:
17106
+ {
17107
+ if (enableSuspenseServerRenderer) {
17108
+ if (current === null) {
17109
+ var _wasHydrated2 = popHydrationState(workInProgress);
17110
+ !_wasHydrated2 ? invariant(false, 'A dehydrated suspense component was completed without a hydrated node. This is probably a bug in React.') : void 0;
17111
+ skipPastDehydratedSuspenseInstance(workInProgress);
17112
+ } else if ((workInProgress.effectTag & DidCapture) === NoEffect) {
17113
+ // This boundary did not suspend so it's now hydrated.
17114
+ // To handle any future suspense cases, we're going to now upgrade it
17115
+ // to a Suspense component. We detach it from the existing current fiber.
17116
+ current.alternate = null;
17117
+ workInProgress.alternate = null;
17118
+ workInProgress.tag = SuspenseComponent;
17119
+ workInProgress.memoizedState = null;
17120
+ workInProgress.stateNode = null;
17121
+ }
17122
+ }
17123
+ break;
17124
+ }
16684
17125
  default:
16685
17126
  invariant(false, 'Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.');
16686
17127
  }
@@ -16771,7 +17212,7 @@ var didWarnAboutUndefinedSnapshotBeforeUpdate = null;
16771
17212
  didWarnAboutUndefinedSnapshotBeforeUpdate = new Set();
16772
17213
  }
16773
17214
 
16774
- var PossiblyWeakSet = typeof WeakSet === 'function' ? WeakSet : Set;
17215
+ var PossiblyWeakSet$1 = typeof WeakSet === 'function' ? WeakSet : Set;
16775
17216
 
16776
17217
  function logError(boundary, errorInfo) {
16777
17218
  var source = errorInfo.source;
@@ -17084,7 +17525,7 @@ function commitLifeCycles(finishedRoot, current$$1, finishedWork, committedExpir
17084
17525
 
17085
17526
  function hideOrUnhideAllChildren(finishedWork, isHidden) {
17086
17527
  if (supportsMutation) {
17087
- // We only have the top Fiber that was inserted but we need recurse down its
17528
+ // We only have the top Fiber that was inserted but we need to recurse down its
17088
17529
  var node = finishedWork;
17089
17530
  while (true) {
17090
17531
  if (node.tag === HostComponent) {
@@ -17352,7 +17793,7 @@ function getHostSibling(fiber) {
17352
17793
  }
17353
17794
  node.sibling.return = node.return;
17354
17795
  node = node.sibling;
17355
- while (node.tag !== HostComponent && node.tag !== HostText) {
17796
+ while (node.tag !== HostComponent && node.tag !== HostText && node.tag !== DehydratedSuspenseComponent) {
17356
17797
  // If it is not host node and, we might have a host node inside it.
17357
17798
  // Try to search down until we find one.
17358
17799
  if (node.effectTag & Placement) {
@@ -17412,7 +17853,7 @@ function commitPlacement(finishedWork) {
17412
17853
  }
17413
17854
 
17414
17855
  var before = getHostSibling(finishedWork);
17415
- // We only have the top Fiber that was inserted but we need recurse down its
17856
+ // We only have the top Fiber that was inserted but we need to recurse down its
17416
17857
  // children to find all the terminal nodes.
17417
17858
  var node = finishedWork;
17418
17859
  while (true) {
@@ -17454,7 +17895,7 @@ function commitPlacement(finishedWork) {
17454
17895
  }
17455
17896
 
17456
17897
  function unmountHostComponents(current$$1) {
17457
- // We only have the top Fiber that was deleted but we need recurse down its
17898
+ // We only have the top Fiber that was deleted but we need to recurse down its
17458
17899
  var node = current$$1;
17459
17900
 
17460
17901
  // Each iteration, currentParent is populated with node's host parent if not
@@ -17499,13 +17940,20 @@ function unmountHostComponents(current$$1) {
17499
17940
  removeChild(currentParent, node.stateNode);
17500
17941
  }
17501
17942
  // Don't visit children because we already visited them.
17943
+ } else if (enableSuspenseServerRenderer && node.tag === DehydratedSuspenseComponent) {
17944
+ // Delete the dehydrated suspense boundary and all of its content.
17945
+ if (currentParentIsContainer) {
17946
+ clearSuspenseBoundaryFromContainer(currentParent, node.stateNode);
17947
+ } else {
17948
+ clearSuspenseBoundary(currentParent, node.stateNode);
17949
+ }
17502
17950
  } else if (node.tag === HostPortal) {
17503
- // When we go into a portal, it becomes the parent to remove from.
17504
- // We will reassign it back when we pop the portal on the way up.
17505
- currentParent = node.stateNode.containerInfo;
17506
- currentParentIsContainer = true;
17507
- // Visit children because portals might contain host components.
17508
17951
  if (node.child !== null) {
17952
+ // When we go into a portal, it becomes the parent to remove from.
17953
+ // We will reassign it back when we pop the portal on the way up.
17954
+ currentParent = node.stateNode.containerInfo;
17955
+ currentParentIsContainer = true;
17956
+ // Visit children because portals might contain host components.
17509
17957
  node.child.return = node;
17510
17958
  node = node.child;
17511
17959
  continue;
@@ -17655,7 +18103,7 @@ function commitWork(current$$1, finishedWork) {
17655
18103
  finishedWork.updateQueue = null;
17656
18104
  var retryCache = finishedWork.stateNode;
17657
18105
  if (retryCache === null) {
17658
- retryCache = finishedWork.stateNode = new PossiblyWeakSet();
18106
+ retryCache = finishedWork.stateNode = new PossiblyWeakSet$1();
17659
18107
  }
17660
18108
  thenables.forEach(function (thenable) {
17661
18109
  // Memoize using the boundary fiber to prevent redundant listeners.
@@ -17690,6 +18138,7 @@ function commitResetTextContent(current$$1) {
17690
18138
  resetTextContent(current$$1.stateNode);
17691
18139
  }
17692
18140
 
18141
+ var PossiblyWeakSet = typeof WeakSet === 'function' ? WeakSet : Set;
17693
18142
  var PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map;
17694
18143
 
17695
18144
  function createRootErrorUpdate(fiber, errorInfo, expirationTime) {
@@ -17748,6 +18197,34 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) {
17748
18197
  return update;
17749
18198
  }
17750
18199
 
18200
+ function attachPingListener(root, renderExpirationTime, thenable) {
18201
+ // Attach a listener to the promise to "ping" the root and retry. But
18202
+ // only if one does not already exist for the current render expiration
18203
+ // time (which acts like a "thread ID" here).
18204
+ var pingCache = root.pingCache;
18205
+ var threadIDs = void 0;
18206
+ if (pingCache === null) {
18207
+ pingCache = root.pingCache = new PossiblyWeakMap();
18208
+ threadIDs = new Set();
18209
+ pingCache.set(thenable, threadIDs);
18210
+ } else {
18211
+ threadIDs = pingCache.get(thenable);
18212
+ if (threadIDs === undefined) {
18213
+ threadIDs = new Set();
18214
+ pingCache.set(thenable, threadIDs);
18215
+ }
18216
+ }
18217
+ if (!threadIDs.has(renderExpirationTime)) {
18218
+ // Memoize using the thread ID to prevent redundant listeners.
18219
+ threadIDs.add(renderExpirationTime);
18220
+ var ping = pingSuspendedRoot.bind(null, root, thenable, renderExpirationTime);
18221
+ if (enableSchedulerTracing) {
18222
+ ping = unstable_wrap(ping);
18223
+ }
18224
+ thenable.then(ping, ping);
18225
+ }
18226
+ }
18227
+
17751
18228
  function throwException(root, returnFiber, sourceFiber, value, renderExpirationTime) {
17752
18229
  // The source fiber did not complete.
17753
18230
  sourceFiber.effectTag |= Incomplete;
@@ -17789,6 +18266,9 @@ function throwException(root, returnFiber, sourceFiber, value, renderExpirationT
17789
18266
  }
17790
18267
  }
17791
18268
  }
18269
+ // If there is a DehydratedSuspenseComponent we don't have to do anything because
18270
+ // if something suspends inside it, we will simply leave that as dehydrated. It
18271
+ // will never timeout.
17792
18272
  _workInProgress = _workInProgress.return;
17793
18273
  } while (_workInProgress !== null);
17794
18274
 
@@ -17852,31 +18332,7 @@ function throwException(root, returnFiber, sourceFiber, value, renderExpirationT
17852
18332
  // Confirmed that the boundary is in a concurrent mode tree. Continue
17853
18333
  // with the normal suspend path.
17854
18334
 
17855
- // Attach a listener to the promise to "ping" the root and retry. But
17856
- // only if one does not already exist for the current render expiration
17857
- // time (which acts like a "thread ID" here).
17858
- var pingCache = root.pingCache;
17859
- var threadIDs = void 0;
17860
- if (pingCache === null) {
17861
- pingCache = root.pingCache = new PossiblyWeakMap();
17862
- threadIDs = new Set();
17863
- pingCache.set(thenable, threadIDs);
17864
- } else {
17865
- threadIDs = pingCache.get(thenable);
17866
- if (threadIDs === undefined) {
17867
- threadIDs = new Set();
17868
- pingCache.set(thenable, threadIDs);
17869
- }
17870
- }
17871
- if (!threadIDs.has(renderExpirationTime)) {
17872
- // Memoize using the thread ID to prevent redundant listeners.
17873
- threadIDs.add(renderExpirationTime);
17874
- var ping = pingSuspendedRoot.bind(null, root, thenable, renderExpirationTime);
17875
- if (enableSchedulerTracing) {
17876
- ping = unstable_wrap(ping);
17877
- }
17878
- thenable.then(ping, ping);
17879
- }
18335
+ attachPingListener(root, renderExpirationTime, thenable);
17880
18336
 
17881
18337
  var absoluteTimeoutMs = void 0;
17882
18338
  if (earliestTimeoutMs === -1) {
@@ -17908,6 +18364,29 @@ function throwException(root, returnFiber, sourceFiber, value, renderExpirationT
17908
18364
  // whole tree.
17909
18365
  renderDidSuspend(root, absoluteTimeoutMs, renderExpirationTime);
17910
18366
 
18367
+ _workInProgress.effectTag |= ShouldCapture;
18368
+ _workInProgress.expirationTime = renderExpirationTime;
18369
+ return;
18370
+ } else if (enableSuspenseServerRenderer && _workInProgress.tag === DehydratedSuspenseComponent) {
18371
+ attachPingListener(root, renderExpirationTime, thenable);
18372
+
18373
+ // Since we already have a current fiber, we can eagerly add a retry listener.
18374
+ var retryCache = _workInProgress.memoizedState;
18375
+ if (retryCache === null) {
18376
+ retryCache = _workInProgress.memoizedState = new PossiblyWeakSet();
18377
+ var _current = _workInProgress.alternate;
18378
+ !_current ? invariant(false, 'A dehydrated suspense boundary must commit before trying to render. This is probably a bug in React.') : void 0;
18379
+ _current.memoizedState = retryCache;
18380
+ }
18381
+ // Memoize using the boundary fiber to prevent redundant listeners.
18382
+ if (!retryCache.has(thenable)) {
18383
+ retryCache.add(thenable);
18384
+ var retry = retryTimedOutBoundary.bind(null, _workInProgress, thenable);
18385
+ if (enableSchedulerTracing) {
18386
+ retry = unstable_wrap(retry);
18387
+ }
18388
+ thenable.then(retry, retry);
18389
+ }
17911
18390
  _workInProgress.effectTag |= ShouldCapture;
17912
18391
  _workInProgress.expirationTime = renderExpirationTime;
17913
18392
  return;
@@ -17985,6 +18464,7 @@ function unwindWork(workInProgress, renderExpirationTime) {
17985
18464
  }
17986
18465
  case HostComponent:
17987
18466
  {
18467
+ // TODO: popHydrationState
17988
18468
  popHostContext(workInProgress);
17989
18469
  return null;
17990
18470
  }
@@ -17998,6 +18478,19 @@ function unwindWork(workInProgress, renderExpirationTime) {
17998
18478
  }
17999
18479
  return null;
18000
18480
  }
18481
+ case DehydratedSuspenseComponent:
18482
+ {
18483
+ if (enableSuspenseServerRenderer) {
18484
+ // TODO: popHydrationState
18485
+ var _effectTag3 = workInProgress.effectTag;
18486
+ if (_effectTag3 & ShouldCapture) {
18487
+ workInProgress.effectTag = _effectTag3 & ~ShouldCapture | DidCapture;
18488
+ // Captured a suspense effect. Re-render the boundary.
18489
+ return workInProgress;
18490
+ }
18491
+ }
18492
+ return null;
18493
+ }
18001
18494
  case HostPortal:
18002
18495
  popHostContainer(workInProgress);
18003
18496
  return null;
@@ -18095,11 +18588,6 @@ if (enableSchedulerTracing) {
18095
18588
  // Used to ensure computeUniqueAsyncExpiration is monotonically decreasing.
18096
18589
  var lastUniqueAsyncExpiration = Sync - 1;
18097
18590
 
18098
- // Represents the expiration time that incoming updates should use. (If this
18099
- // is NoWork, use the default strategy: async updates in async mode, sync
18100
- // updates in sync mode.)
18101
- var expirationContext = NoWork;
18102
-
18103
18591
  var isWorking = false;
18104
18592
 
18105
18593
  // The next work in progress fiber that we're currently working on.
@@ -18395,6 +18883,10 @@ function commitPassiveEffects(root, firstEffect) {
18395
18883
  if (rootExpirationTime !== NoWork) {
18396
18884
  requestWork(root, rootExpirationTime);
18397
18885
  }
18886
+ // Flush any sync work that was scheduled by effects
18887
+ if (!isBatchingUpdates && !isRendering) {
18888
+ performSyncWork();
18889
+ }
18398
18890
  }
18399
18891
 
18400
18892
  function isAlreadyFailedLegacyErrorBoundary(instance) {
@@ -18569,7 +19061,9 @@ function commitRoot(root, finishedWork) {
18569
19061
  // here because that code is still in flux.
18570
19062
  callback = unstable_wrap(callback);
18571
19063
  }
18572
- passiveEffectCallbackHandle = schedulePassiveEffects(callback);
19064
+ passiveEffectCallbackHandle = unstable_runWithPriority(unstable_NormalPriority, function () {
19065
+ return schedulePassiveEffects(callback);
19066
+ });
18573
19067
  passiveEffectCallback = callback;
18574
19068
  }
18575
19069
 
@@ -19158,7 +19652,7 @@ function renderRoot(root, isYieldy) {
19158
19652
  return;
19159
19653
  } else if (
19160
19654
  // There's no lower priority work, but we're rendering asynchronously.
19161
- // Synchronsouly attempt to render the same level one more time. This is
19655
+ // Synchronously attempt to render the same level one more time. This is
19162
19656
  // similar to a suspend, but without a timeout because we're not waiting
19163
19657
  // for a promise to resolve.
19164
19658
  !root.didError && isYieldy) {
@@ -19263,49 +19757,50 @@ function computeUniqueAsyncExpiration() {
19263
19757
  }
19264
19758
 
19265
19759
  function computeExpirationForFiber(currentTime, fiber) {
19760
+ var priorityLevel = unstable_getCurrentPriorityLevel();
19761
+
19266
19762
  var expirationTime = void 0;
19267
- if (expirationContext !== NoWork) {
19268
- // An explicit expiration context was set;
19269
- expirationTime = expirationContext;
19270
- } else if (isWorking) {
19271
- if (isCommitting$1) {
19272
- // Updates that occur during the commit phase should have sync priority
19273
- // by default.
19274
- expirationTime = Sync;
19275
- } else {
19276
- // Updates during the render phase should expire at the same time as
19277
- // the work that is being rendered.
19278
- expirationTime = nextRenderExpirationTime;
19279
- }
19763
+ if ((fiber.mode & ConcurrentMode) === NoContext) {
19764
+ // Outside of concurrent mode, updates are always synchronous.
19765
+ expirationTime = Sync;
19766
+ } else if (isWorking && !isCommitting$1) {
19767
+ // During render phase, updates expire during as the current render.
19768
+ expirationTime = nextRenderExpirationTime;
19280
19769
  } else {
19281
- // No explicit expiration context was set, and we're not currently
19282
- // performing work. Calculate a new expiration time.
19283
- if (fiber.mode & ConcurrentMode) {
19284
- if (isBatchingInteractiveUpdates) {
19285
- // This is an interactive update
19770
+ switch (priorityLevel) {
19771
+ case unstable_ImmediatePriority:
19772
+ expirationTime = Sync;
19773
+ break;
19774
+ case unstable_UserBlockingPriority:
19286
19775
  expirationTime = computeInteractiveExpiration(currentTime);
19287
- } else {
19288
- // This is an async update
19776
+ break;
19777
+ case unstable_NormalPriority:
19778
+ // This is a normal, concurrent update
19289
19779
  expirationTime = computeAsyncExpiration(currentTime);
19290
- }
19291
- // If we're in the middle of rendering a tree, do not update at the same
19292
- // expiration time that is already rendering.
19293
- if (nextRoot !== null && expirationTime === nextRenderExpirationTime) {
19294
- expirationTime -= 1;
19295
- }
19296
- } else {
19297
- // This is a sync update
19298
- expirationTime = Sync;
19780
+ break;
19781
+ case unstable_LowPriority:
19782
+ case unstable_IdlePriority:
19783
+ expirationTime = Never;
19784
+ break;
19785
+ default:
19786
+ invariant(false, 'Unknown priority level. This error is likely caused by a bug in React. Please file an issue.');
19299
19787
  }
19300
- }
19301
- if (isBatchingInteractiveUpdates) {
19302
- // This is an interactive update. Keep track of the lowest pending
19303
- // interactive expiration time. This allows us to synchronously flush
19304
- // all interactive updates when needed.
19305
- if (lowestPriorityPendingInteractiveExpirationTime === NoWork || expirationTime < lowestPriorityPendingInteractiveExpirationTime) {
19306
- lowestPriorityPendingInteractiveExpirationTime = expirationTime;
19788
+
19789
+ // If we're in the middle of rendering a tree, do not update at the same
19790
+ // expiration time that is already rendering.
19791
+ if (nextRoot !== null && expirationTime === nextRenderExpirationTime) {
19792
+ expirationTime -= 1;
19307
19793
  }
19308
19794
  }
19795
+
19796
+ // Keep track of the lowest pending interactive expiration time. This
19797
+ // allows us to synchronously flush all interactive updates
19798
+ // when needed.
19799
+ // TODO: Move this to renderer?
19800
+ if (priorityLevel === unstable_UserBlockingPriority && (lowestPriorityPendingInteractiveExpirationTime === NoWork || expirationTime < lowestPriorityPendingInteractiveExpirationTime)) {
19801
+ lowestPriorityPendingInteractiveExpirationTime = expirationTime;
19802
+ }
19803
+
19309
19804
  return expirationTime;
19310
19805
  }
19311
19806
 
@@ -19352,7 +19847,21 @@ function retryTimedOutBoundary(boundaryFiber, thenable) {
19352
19847
  // The boundary fiber (a Suspense component) previously timed out and was
19353
19848
  // rendered in its fallback state. One of the promises that suspended it has
19354
19849
  // resolved, which means at least part of the tree was likely unblocked. Try
19355
- var retryCache = boundaryFiber.stateNode;
19850
+ var retryCache = void 0;
19851
+ if (enableSuspenseServerRenderer) {
19852
+ switch (boundaryFiber.tag) {
19853
+ case SuspenseComponent:
19854
+ retryCache = boundaryFiber.stateNode;
19855
+ break;
19856
+ case DehydratedSuspenseComponent:
19857
+ retryCache = boundaryFiber.memoizedState;
19858
+ break;
19859
+ default:
19860
+ invariant(false, 'Pinged unknown suspense boundary type. This is probably a bug in React.');
19861
+ }
19862
+ } else {
19863
+ retryCache = boundaryFiber.stateNode;
19864
+ }
19356
19865
  if (retryCache !== null) {
19357
19866
  // The thenable resolved, so we no longer need to memoize, because it will
19358
19867
  // never be thrown again.
@@ -19451,7 +19960,7 @@ function scheduleWorkToRoot(fiber, expirationTime) {
19451
19960
  function warnIfNotCurrentlyBatchingInDev(fiber) {
19452
19961
  {
19453
19962
  if (isRendering === false && isBatchingUpdates === false) {
19454
- 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));
19963
+ 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));
19455
19964
  }
19456
19965
  }
19457
19966
  }
@@ -19498,13 +20007,9 @@ function scheduleWork(fiber, expirationTime) {
19498
20007
  }
19499
20008
 
19500
20009
  function syncUpdates(fn, a, b, c, d) {
19501
- var previousExpirationContext = expirationContext;
19502
- expirationContext = Sync;
19503
- try {
20010
+ return unstable_runWithPriority(unstable_ImmediatePriority, function () {
19504
20011
  return fn(a, b, c, d);
19505
- } finally {
19506
- expirationContext = previousExpirationContext;
19507
- }
20012
+ });
19508
20013
  }
19509
20014
 
19510
20015
  // TODO: Everything below this is written as if it has been lifted to the
@@ -19525,7 +20030,6 @@ var unhandledError = null;
19525
20030
 
19526
20031
  var isBatchingUpdates = false;
19527
20032
  var isUnbatchingUpdates = false;
19528
- var isBatchingInteractiveUpdates = false;
19529
20033
 
19530
20034
  var completedBatches = null;
19531
20035
 
@@ -19999,7 +20503,9 @@ function completeRoot(root, finishedWork, expirationTime) {
19999
20503
  lastCommittedRootDuringThisBatch = root;
20000
20504
  nestedUpdateCount = 0;
20001
20505
  }
20002
- commitRoot(root, finishedWork);
20506
+ unstable_runWithPriority(unstable_ImmediatePriority, function () {
20507
+ commitRoot(root, finishedWork);
20508
+ });
20003
20509
  }
20004
20510
 
20005
20511
  function onUncaughtError(error) {
@@ -20057,9 +20563,6 @@ function flushSync(fn, a) {
20057
20563
  }
20058
20564
 
20059
20565
  function interactiveUpdates$1(fn, a, b) {
20060
- if (isBatchingInteractiveUpdates) {
20061
- return fn(a, b);
20062
- }
20063
20566
  // If there are any pending interactive updates, synchronously flush them.
20064
20567
  // This needs to happen before we read any handlers, because the effect of
20065
20568
  // the previous event may influence which handlers are called during
@@ -20069,14 +20572,13 @@ function interactiveUpdates$1(fn, a, b) {
20069
20572
  performWork(lowestPriorityPendingInteractiveExpirationTime, false);
20070
20573
  lowestPriorityPendingInteractiveExpirationTime = NoWork;
20071
20574
  }
20072
- var previousIsBatchingInteractiveUpdates = isBatchingInteractiveUpdates;
20073
20575
  var previousIsBatchingUpdates = isBatchingUpdates;
20074
- isBatchingInteractiveUpdates = true;
20075
20576
  isBatchingUpdates = true;
20076
20577
  try {
20077
- return fn(a, b);
20578
+ return unstable_runWithPriority(unstable_UserBlockingPriority, function () {
20579
+ return fn(a, b);
20580
+ });
20078
20581
  } finally {
20079
- isBatchingInteractiveUpdates = previousIsBatchingInteractiveUpdates;
20080
20582
  isBatchingUpdates = previousIsBatchingUpdates;
20081
20583
  if (!isBatchingUpdates && !isRendering) {
20082
20584
  performSyncWork();
@@ -20339,7 +20841,7 @@ implementation) {
20339
20841
 
20340
20842
  // TODO: this is special because it gets imported during build.
20341
20843
 
20342
- var ReactVersion = '16.8.0';
20844
+ var ReactVersion = '16.8.4';
20343
20845
 
20344
20846
  // TODO: This type is shared between the reconciler and ReactDOM, but will
20345
20847
  // eventually be lifted out to the renderer.
@@ -20729,7 +21231,7 @@ var ReactDOM = {
20729
21231
  hydrate: function (element, container, callback) {
20730
21232
  !isValidContainer(container) ? invariant(false, 'Target container is not a DOM element.') : void 0;
20731
21233
  {
20732
- !!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 root.render(element, {hydrate: true})?', enableStableConcurrentModeAPIs ? 'createRoot' : 'unstable_createRoot') : void 0;
21234
+ !!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;
20733
21235
  }
20734
21236
  // TODO: throw or warn if we couldn't hydrate?
20735
21237
  return legacyRenderSubtreeIntoContainer(null, element, container, true, callback);