react-dom 16.8.1 → 16.8.5

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 +67 -36
  3. package/cjs/react-dom-server.browser.production.min.js +17 -16
  4. package/cjs/react-dom-server.node.development.js +67 -36
  5. package/cjs/react-dom-server.node.production.min.js +18 -17
  6. package/cjs/react-dom-test-utils.development.js +2 -2
  7. package/cjs/react-dom-test-utils.production.min.js +1 -1
  8. package/cjs/react-dom-unstable-fire.development.js +709 -213
  9. package/cjs/react-dom-unstable-fire.production.min.js +252 -251
  10. package/cjs/react-dom-unstable-fire.profiling.min.js +176 -173
  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 +709 -213
  18. package/cjs/react-dom.production.min.js +252 -251
  19. package/cjs/react-dom.profiling.min.js +176 -173
  20. package/package.json +2 -2
  21. package/umd/react-dom-server.browser.development.js +67 -36
  22. package/umd/react-dom-server.browser.production.min.js +22 -21
  23. package/umd/react-dom-test-utils.development.js +2 -2
  24. package/umd/react-dom-test-utils.production.min.js +1 -1
  25. package/umd/react-dom-unstable-fire.development.js +717 -213
  26. package/umd/react-dom-unstable-fire.production.min.js +208 -207
  27. package/umd/react-dom-unstable-fire.profiling.min.js +208 -208
  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 +717 -213
  33. package/umd/react-dom.production.min.js +208 -207
  34. package/umd/react-dom.profiling.min.js +208 -208
@@ -1,4 +1,4 @@
1
- /** @license React v16.8.1
1
+ /** @license React v16.8.5
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;
@@ -2901,12 +2902,15 @@ var capitalize = function (token) {
2901
2902
  attributeName, 'http://www.w3.org/XML/1998/namespace');
2902
2903
  });
2903
2904
 
2904
- // Special case: this attribute exists both in HTML and SVG.
2905
- // Its "tabindex" attribute name is case-sensitive in SVG so we can't just use
2906
- // its React `tabIndex` name, like we do for attributes that exist only in HTML.
2907
- properties.tabIndex = new PropertyInfoRecord('tabIndex', STRING, false, // mustUseProperty
2908
- 'tabindex', // attributeName
2909
- 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
+ );
2910
2914
 
2911
2915
  /**
2912
2916
  * Get the value for a property on a node. Only used in DEV for SSR validation.
@@ -3250,7 +3254,7 @@ var enableProfilerTimer = true;
3250
3254
  var enableSchedulerTracing = true;
3251
3255
 
3252
3256
  // Only used in www builds.
3253
- // TODO: true? Here it might just be false.
3257
+ var enableSuspenseServerRenderer = false; // TODO: true? Here it might just be false.
3254
3258
 
3255
3259
  // Only used in www builds.
3256
3260
 
@@ -7729,14 +7733,25 @@ function createElement(type, props, rootContainerElement, parentNamespace) {
7729
7733
  // See discussion in https://github.com/facebook/react/pull/6896
7730
7734
  // and discussion in https://bugzilla.mozilla.org/show_bug.cgi?id=1276240
7731
7735
  domElement = ownerDocument.createElement(type);
7732
- // Normally attributes are assigned in `setInitialDOMProperties`, however the `multiple`
7733
- // attribute on `select`s needs to be added before `option`s are inserted. This prevents
7734
- // a bug where the `select` does not scroll to the correct option because singular
7735
- // `select` elements automatically pick the first item.
7736
+ // Normally attributes are assigned in `setInitialDOMProperties`, however the `multiple` and `size`
7737
+ // attributes on `select`s needs to be added before `option`s are inserted.
7738
+ // This prevents:
7739
+ // - a bug where the `select` does not scroll to the correct option because singular
7740
+ // `select` elements automatically pick the first item #13222
7741
+ // - a bug where the `select` set the first item as selected despite the `size` attribute #14239
7736
7742
  // See https://github.com/facebook/react/issues/13222
7737
- if (type === 'select' && props.multiple) {
7743
+ // and https://github.com/facebook/react/issues/14239
7744
+ if (type === 'select') {
7738
7745
  var node = domElement;
7739
- node.multiple = true;
7746
+ if (props.multiple) {
7747
+ node.multiple = true;
7748
+ } else if (props.size) {
7749
+ // Setting a size greater than 1 causes a select to behave like `multiple=true`, where
7750
+ // it is possible that no option is selected.
7751
+ //
7752
+ // This is only necessary when a select in "single selection mode".
7753
+ node.size = props.size;
7754
+ }
7740
7755
  }
7741
7756
  }
7742
7757
  } else {
@@ -8710,8 +8725,16 @@ var unstable_now = _ReactInternals$Sched.unstable_now;
8710
8725
  var unstable_scheduleCallback = _ReactInternals$Sched.unstable_scheduleCallback;
8711
8726
  var unstable_shouldYield = _ReactInternals$Sched.unstable_shouldYield;
8712
8727
  var unstable_getFirstCallbackNode = _ReactInternals$Sched.unstable_getFirstCallbackNode;
8728
+ var unstable_runWithPriority = _ReactInternals$Sched.unstable_runWithPriority;
8729
+ var unstable_next = _ReactInternals$Sched.unstable_next;
8713
8730
  var unstable_continueExecution = _ReactInternals$Sched.unstable_continueExecution;
8714
8731
  var unstable_pauseExecution = _ReactInternals$Sched.unstable_pauseExecution;
8732
+ var unstable_getCurrentPriorityLevel = _ReactInternals$Sched.unstable_getCurrentPriorityLevel;
8733
+ var unstable_ImmediatePriority = _ReactInternals$Sched.unstable_ImmediatePriority;
8734
+ var unstable_UserBlockingPriority = _ReactInternals$Sched.unstable_UserBlockingPriority;
8735
+ var unstable_NormalPriority = _ReactInternals$Sched.unstable_NormalPriority;
8736
+ var unstable_LowPriority = _ReactInternals$Sched.unstable_LowPriority;
8737
+ var unstable_IdlePriority = _ReactInternals$Sched.unstable_IdlePriority;
8715
8738
 
8716
8739
  // Renderers that don't support persistence
8717
8740
  // can re-export everything from this module.
@@ -8736,6 +8759,9 @@ var SUPPRESS_HYDRATION_WARNING = void 0;
8736
8759
  SUPPRESS_HYDRATION_WARNING = 'suppressHydrationWarning';
8737
8760
  }
8738
8761
 
8762
+ var SUSPENSE_START_DATA = '$';
8763
+ var SUSPENSE_END_DATA = '/$';
8764
+
8739
8765
  var STYLE = 'style';
8740
8766
 
8741
8767
  var eventsEnabled = null;
@@ -8964,6 +8990,43 @@ function removeChildFromContainer(container, child) {
8964
8990
  }
8965
8991
  }
8966
8992
 
8993
+ function clearSuspenseBoundary(parentInstance, suspenseInstance) {
8994
+ var node = suspenseInstance;
8995
+ // Delete all nodes within this suspense boundary.
8996
+ // There might be nested nodes so we need to keep track of how
8997
+ // deep we are and only break out when we're back on top.
8998
+ var depth = 0;
8999
+ do {
9000
+ var nextNode = node.nextSibling;
9001
+ parentInstance.removeChild(node);
9002
+ if (nextNode && nextNode.nodeType === COMMENT_NODE) {
9003
+ var data = nextNode.data;
9004
+ if (data === SUSPENSE_END_DATA) {
9005
+ if (depth === 0) {
9006
+ parentInstance.removeChild(nextNode);
9007
+ return;
9008
+ } else {
9009
+ depth--;
9010
+ }
9011
+ } else if (data === SUSPENSE_START_DATA) {
9012
+ depth++;
9013
+ }
9014
+ }
9015
+ node = nextNode;
9016
+ } while (node);
9017
+ // TODO: Warn, we didn't find the end comment boundary.
9018
+ }
9019
+
9020
+ function clearSuspenseBoundaryFromContainer(container, suspenseInstance) {
9021
+ if (container.nodeType === COMMENT_NODE) {
9022
+ clearSuspenseBoundary(container.parentNode, suspenseInstance);
9023
+ } else if (container.nodeType === ELEMENT_NODE) {
9024
+ clearSuspenseBoundary(container, suspenseInstance);
9025
+ } else {
9026
+ // Document nodes should never contain suspense boundaries.
9027
+ }
9028
+ }
9029
+
8967
9030
  function hideInstance(instance) {
8968
9031
  // TODO: Does this work for all element types? What about MathML? Should we
8969
9032
  // pass host context to this method?
@@ -9009,10 +9072,19 @@ function canHydrateTextInstance(instance, text) {
9009
9072
  return instance;
9010
9073
  }
9011
9074
 
9075
+ function canHydrateSuspenseInstance(instance) {
9076
+ if (instance.nodeType !== COMMENT_NODE) {
9077
+ // Empty strings are not parsed by HTML so there won't be a correct match here.
9078
+ return null;
9079
+ }
9080
+ // This has now been refined to a suspense node.
9081
+ return instance;
9082
+ }
9083
+
9012
9084
  function getNextHydratableSibling(instance) {
9013
9085
  var node = instance.nextSibling;
9014
9086
  // Skip non-hydratable nodes.
9015
- while (node && node.nodeType !== ELEMENT_NODE && node.nodeType !== TEXT_NODE) {
9087
+ while (node && node.nodeType !== ELEMENT_NODE && node.nodeType !== TEXT_NODE && (!enableSuspenseServerRenderer || node.nodeType !== COMMENT_NODE || node.data !== SUSPENSE_START_DATA)) {
9016
9088
  node = node.nextSibling;
9017
9089
  }
9018
9090
  return node;
@@ -9021,7 +9093,7 @@ function getNextHydratableSibling(instance) {
9021
9093
  function getFirstHydratableChild(parentInstance) {
9022
9094
  var next = parentInstance.firstChild;
9023
9095
  // Skip non-hydratable nodes.
9024
- while (next && next.nodeType !== ELEMENT_NODE && next.nodeType !== TEXT_NODE) {
9096
+ while (next && next.nodeType !== ELEMENT_NODE && next.nodeType !== TEXT_NODE && (!enableSuspenseServerRenderer || next.nodeType !== COMMENT_NODE || next.data !== SUSPENSE_START_DATA)) {
9025
9097
  next = next.nextSibling;
9026
9098
  }
9027
9099
  return next;
@@ -9045,6 +9117,31 @@ function hydrateTextInstance(textInstance, text, internalInstanceHandle) {
9045
9117
  return diffHydratedText(textInstance, text);
9046
9118
  }
9047
9119
 
9120
+ function getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance) {
9121
+ var node = suspenseInstance.nextSibling;
9122
+ // Skip past all nodes within this suspense boundary.
9123
+ // There might be nested nodes so we need to keep track of how
9124
+ // deep we are and only break out when we're back on top.
9125
+ var depth = 0;
9126
+ while (node) {
9127
+ if (node.nodeType === COMMENT_NODE) {
9128
+ var data = node.data;
9129
+ if (data === SUSPENSE_END_DATA) {
9130
+ if (depth === 0) {
9131
+ return getNextHydratableSibling(node);
9132
+ } else {
9133
+ depth--;
9134
+ }
9135
+ } else if (data === SUSPENSE_START_DATA) {
9136
+ depth++;
9137
+ }
9138
+ }
9139
+ node = node.nextSibling;
9140
+ }
9141
+ // TODO: Warn, we didn't find the end comment boundary.
9142
+ return null;
9143
+ }
9144
+
9048
9145
  function didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, text) {
9049
9146
  {
9050
9147
  warnForUnmatchedText(textInstance, text);
@@ -9061,6 +9158,8 @@ function didNotHydrateContainerInstance(parentContainer, instance) {
9061
9158
  {
9062
9159
  if (instance.nodeType === ELEMENT_NODE) {
9063
9160
  warnForDeletedHydratableElement(parentContainer, instance);
9161
+ } else if (instance.nodeType === COMMENT_NODE) {
9162
+ // TODO: warnForDeletedHydratableSuspenseBoundary
9064
9163
  } else {
9065
9164
  warnForDeletedHydratableText(parentContainer, instance);
9066
9165
  }
@@ -9071,6 +9170,8 @@ function didNotHydrateInstance(parentType, parentProps, parentInstance, instance
9071
9170
  if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
9072
9171
  if (instance.nodeType === ELEMENT_NODE) {
9073
9172
  warnForDeletedHydratableElement(parentInstance, instance);
9173
+ } else if (instance.nodeType === COMMENT_NODE) {
9174
+ // TODO: warnForDeletedHydratableSuspenseBoundary
9074
9175
  } else {
9075
9176
  warnForDeletedHydratableText(parentInstance, instance);
9076
9177
  }
@@ -9089,6 +9190,8 @@ function didNotFindHydratableContainerTextInstance(parentContainer, text) {
9089
9190
  }
9090
9191
  }
9091
9192
 
9193
+
9194
+
9092
9195
  function didNotFindHydratableInstance(parentType, parentProps, parentInstance, type, props) {
9093
9196
  if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
9094
9197
  warnForInsertedHydratedElement(parentInstance, type, props);
@@ -9101,6 +9204,12 @@ function didNotFindHydratableTextInstance(parentType, parentProps, parentInstanc
9101
9204
  }
9102
9205
  }
9103
9206
 
9207
+ function didNotFindHydratableSuspenseInstance(parentType, parentProps, parentInstance) {
9208
+ if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
9209
+ // TODO: warnForInsertedHydratedSuspense(parentInstance);
9210
+ }
9211
+ }
9212
+
9104
9213
  // Prefix measurements so that it's possible to filter them.
9105
9214
  // Longer prefixes are hard to read in DevTools.
9106
9215
  var reactEmoji = '\u269B';
@@ -9356,7 +9465,7 @@ function stopFailedWorkTimer(fiber) {
9356
9465
  return;
9357
9466
  }
9358
9467
  fiber._debugIsCurrentlyTiming = false;
9359
- var warning = fiber.tag === SuspenseComponent ? 'Rendering was suspended' : 'An error was thrown inside this error boundary';
9468
+ var warning = fiber.tag === SuspenseComponent || fiber.tag === DehydratedSuspenseComponent ? 'Rendering was suspended' : 'An error was thrown inside this error boundary';
9360
9469
  endFiberMark(fiber, null, warning);
9361
9470
  }
9362
9471
  }
@@ -10025,6 +10134,7 @@ function FiberNode(tag, pendingProps, key, mode) {
10025
10134
  this._debugSource = null;
10026
10135
  this._debugOwner = null;
10027
10136
  this._debugIsCurrentlyTiming = false;
10137
+ this._debugHookTypes = null;
10028
10138
  if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') {
10029
10139
  Object.preventExtensions(this);
10030
10140
  }
@@ -10092,6 +10202,7 @@ function createWorkInProgress(current, pendingProps, expirationTime) {
10092
10202
  workInProgress._debugID = current._debugID;
10093
10203
  workInProgress._debugSource = current._debugSource;
10094
10204
  workInProgress._debugOwner = current._debugOwner;
10205
+ workInProgress._debugHookTypes = current._debugHookTypes;
10095
10206
  }
10096
10207
 
10097
10208
  workInProgress.alternate = current;
@@ -10359,6 +10470,7 @@ function assignFiberPropertiesInDEV(target, source) {
10359
10470
  target._debugSource = source._debugSource;
10360
10471
  target._debugOwner = source._debugOwner;
10361
10472
  target._debugIsCurrentlyTiming = source._debugIsCurrentlyTiming;
10473
+ target._debugHookTypes = source._debugHookTypes;
10362
10474
  return target;
10363
10475
  }
10364
10476
 
@@ -12176,7 +12288,7 @@ function ChildReconciler(shouldTrackSideEffects) {
12176
12288
  }
12177
12289
 
12178
12290
  function reconcileChildrenArray(returnFiber, currentFirstChild, newChildren, expirationTime) {
12179
- // This algorithm can't optimize by searching from boths ends since we
12291
+ // This algorithm can't optimize by searching from both ends since we
12180
12292
  // don't have backpointers on fibers. I'm trying to see how far we can get
12181
12293
  // with that model. If it ends up not being worth the tradeoffs, we can
12182
12294
  // add it later.
@@ -12757,7 +12869,6 @@ var currentlyRenderingFiber$1 = null;
12757
12869
  // current hook list is the list that belongs to the current fiber. The
12758
12870
  // work-in-progress hook list is a new list that will be added to the
12759
12871
  // work-in-progress fiber.
12760
- var firstCurrentHook = null;
12761
12872
  var currentHook = null;
12762
12873
  var nextCurrentHook = null;
12763
12874
  var firstWorkInProgressHook = null;
@@ -12787,45 +12898,73 @@ var RE_RENDER_LIMIT = 25;
12787
12898
  // In DEV, this is the name of the currently executing primitive hook
12788
12899
  var currentHookNameInDev = null;
12789
12900
 
12790
- function warnOnHookMismatchInDev() {
12901
+ // In DEV, this list ensures that hooks are called in the same order between renders.
12902
+ // The list stores the order of hooks used during the initial render (mount).
12903
+ // Subsequent renders (updates) reference this list.
12904
+ var hookTypesDev = null;
12905
+ var hookTypesUpdateIndexDev = -1;
12906
+
12907
+ function mountHookTypesDev() {
12908
+ {
12909
+ var hookName = currentHookNameInDev;
12910
+
12911
+ if (hookTypesDev === null) {
12912
+ hookTypesDev = [hookName];
12913
+ } else {
12914
+ hookTypesDev.push(hookName);
12915
+ }
12916
+ }
12917
+ }
12918
+
12919
+ function updateHookTypesDev() {
12920
+ {
12921
+ var hookName = currentHookNameInDev;
12922
+
12923
+ if (hookTypesDev !== null) {
12924
+ hookTypesUpdateIndexDev++;
12925
+ if (hookTypesDev[hookTypesUpdateIndexDev] !== hookName) {
12926
+ warnOnHookMismatchInDev(hookName);
12927
+ }
12928
+ }
12929
+ }
12930
+ }
12931
+
12932
+ function warnOnHookMismatchInDev(currentHookName) {
12791
12933
  {
12792
12934
  var componentName = getComponentName(currentlyRenderingFiber$1.type);
12793
12935
  if (!didWarnAboutMismatchedHooksForComponent.has(componentName)) {
12794
12936
  didWarnAboutMismatchedHooksForComponent.add(componentName);
12795
12937
 
12796
- var secondColumnStart = 22;
12938
+ if (hookTypesDev !== null) {
12939
+ var table = '';
12797
12940
 
12798
- var table = '';
12799
- var prevHook = firstCurrentHook;
12800
- var nextHook = firstWorkInProgressHook;
12801
- var n = 1;
12802
- while (prevHook !== null && nextHook !== null) {
12803
- var oldHookName = prevHook._debugType;
12804
- var newHookName = nextHook._debugType;
12941
+ var secondColumnStart = 30;
12805
12942
 
12806
- var row = n + '. ' + oldHookName;
12943
+ for (var i = 0; i <= hookTypesUpdateIndexDev; i++) {
12944
+ var oldHookName = hookTypesDev[i];
12945
+ var newHookName = i === hookTypesUpdateIndexDev ? currentHookName : oldHookName;
12807
12946
 
12808
- // Extra space so second column lines up
12809
- // lol @ IE not supporting String#repeat
12810
- while (row.length < secondColumnStart) {
12811
- row += ' ';
12812
- }
12947
+ var row = i + 1 + '. ' + oldHookName;
12813
12948
 
12814
- row += newHookName + '\n';
12949
+ // Extra space so second column lines up
12950
+ // lol @ IE not supporting String#repeat
12951
+ while (row.length < secondColumnStart) {
12952
+ row += ' ';
12953
+ }
12815
12954
 
12816
- table += row;
12817
- prevHook = prevHook.next;
12818
- nextHook = nextHook.next;
12819
- n++;
12820
- }
12955
+ row += newHookName + '\n';
12956
+
12957
+ table += row;
12958
+ }
12821
12959
 
12822
- 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);
12960
+ 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);
12961
+ }
12823
12962
  }
12824
12963
  }
12825
12964
  }
12826
12965
 
12827
12966
  function throwInvalidHookError() {
12828
- invariant(false, 'Hooks can only be called inside the body of a function component. (https://fb.me/react-invalid-hook-call)');
12967
+ invariant(false, 'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.');
12829
12968
  }
12830
12969
 
12831
12970
  function areHookInputsEqual(nextDeps, prevDeps) {
@@ -12855,7 +12994,12 @@ function areHookInputsEqual(nextDeps, prevDeps) {
12855
12994
  function renderWithHooks(current, workInProgress, Component, props, refOrContext, nextRenderExpirationTime) {
12856
12995
  renderExpirationTime = nextRenderExpirationTime;
12857
12996
  currentlyRenderingFiber$1 = workInProgress;
12858
- firstCurrentHook = nextCurrentHook = current !== null ? current.memoizedState : null;
12997
+ nextCurrentHook = current !== null ? current.memoizedState : null;
12998
+
12999
+ {
13000
+ hookTypesDev = current !== null ? current._debugHookTypes : null;
13001
+ hookTypesUpdateIndexDev = -1;
13002
+ }
12859
13003
 
12860
13004
  // The following should have already been reset
12861
13005
  // currentHook = null;
@@ -12869,8 +13013,26 @@ function renderWithHooks(current, workInProgress, Component, props, refOrContext
12869
13013
  // numberOfReRenders = 0;
12870
13014
  // sideEffectTag = 0;
12871
13015
 
13016
+ // TODO Warn if no hooks are used at all during mount, then some are used during update.
13017
+ // Currently we will identify the update render as a mount because nextCurrentHook === null.
13018
+ // This is tricky because it's valid for certain types of components (e.g. React.lazy)
13019
+
13020
+ // Using nextCurrentHook to differentiate between mount/update only works if at least one stateful hook is used.
13021
+ // Non-stateful hooks (e.g. context) don't get added to memoizedState,
13022
+ // so nextCurrentHook would be null during updates and mounts.
12872
13023
  {
12873
- ReactCurrentDispatcher$1.current = nextCurrentHook === null ? HooksDispatcherOnMountInDEV : HooksDispatcherOnUpdateInDEV;
13024
+ if (nextCurrentHook !== null) {
13025
+ ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV;
13026
+ } else if (hookTypesDev !== null) {
13027
+ // This dispatcher handles an edge case where a component is updating,
13028
+ // but no stateful hooks have been used.
13029
+ // We want to match the production code behavior (which will use HooksDispatcherOnMount),
13030
+ // but with the extra DEV validation to ensure hooks ordering hasn't changed.
13031
+ // This dispatcher does that.
13032
+ ReactCurrentDispatcher$1.current = HooksDispatcherOnMountWithHookTypesInDEV;
13033
+ } else {
13034
+ ReactCurrentDispatcher$1.current = HooksDispatcherOnMountInDEV;
13035
+ }
12874
13036
  }
12875
13037
 
12876
13038
  var children = Component(props, refOrContext);
@@ -12881,13 +13043,18 @@ function renderWithHooks(current, workInProgress, Component, props, refOrContext
12881
13043
  numberOfReRenders += 1;
12882
13044
 
12883
13045
  // Start over from the beginning of the list
12884
- firstCurrentHook = nextCurrentHook = current !== null ? current.memoizedState : null;
13046
+ nextCurrentHook = current !== null ? current.memoizedState : null;
12885
13047
  nextWorkInProgressHook = firstWorkInProgressHook;
12886
13048
 
12887
13049
  currentHook = null;
12888
13050
  workInProgressHook = null;
12889
13051
  componentUpdateQueue = null;
12890
13052
 
13053
+ {
13054
+ // Also validate hook order for cascading updates.
13055
+ hookTypesUpdateIndexDev = -1;
13056
+ }
13057
+
12891
13058
  ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV;
12892
13059
 
12893
13060
  children = Component(props, refOrContext);
@@ -12897,10 +13064,6 @@ function renderWithHooks(current, workInProgress, Component, props, refOrContext
12897
13064
  numberOfReRenders = 0;
12898
13065
  }
12899
13066
 
12900
- {
12901
- currentHookNameInDev = null;
12902
- }
12903
-
12904
13067
  // We can assume the previous dispatcher is always this one, since we set it
12905
13068
  // at the beginning of the render phase and there's no re-entrancy.
12906
13069
  ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
@@ -12912,18 +13075,29 @@ function renderWithHooks(current, workInProgress, Component, props, refOrContext
12912
13075
  renderedWork.updateQueue = componentUpdateQueue;
12913
13076
  renderedWork.effectTag |= sideEffectTag;
12914
13077
 
13078
+ {
13079
+ renderedWork._debugHookTypes = hookTypesDev;
13080
+ }
13081
+
13082
+ // This check uses currentHook so that it works the same in DEV and prod bundles.
13083
+ // hookTypesDev could catch more cases (e.g. context) but only in DEV bundles.
12915
13084
  var didRenderTooFewHooks = currentHook !== null && currentHook.next !== null;
12916
13085
 
12917
13086
  renderExpirationTime = NoWork;
12918
13087
  currentlyRenderingFiber$1 = null;
12919
13088
 
12920
- firstCurrentHook = null;
12921
13089
  currentHook = null;
12922
13090
  nextCurrentHook = null;
12923
13091
  firstWorkInProgressHook = null;
12924
13092
  workInProgressHook = null;
12925
13093
  nextWorkInProgressHook = null;
12926
13094
 
13095
+ {
13096
+ currentHookNameInDev = null;
13097
+ hookTypesDev = null;
13098
+ hookTypesUpdateIndexDev = -1;
13099
+ }
13100
+
12927
13101
  remainingExpirationTime = NoWork;
12928
13102
  componentUpdateQueue = null;
12929
13103
  sideEffectTag = 0;
@@ -12957,21 +13131,23 @@ function resetHooks() {
12957
13131
  renderExpirationTime = NoWork;
12958
13132
  currentlyRenderingFiber$1 = null;
12959
13133
 
12960
- firstCurrentHook = null;
12961
13134
  currentHook = null;
12962
13135
  nextCurrentHook = null;
12963
13136
  firstWorkInProgressHook = null;
12964
13137
  workInProgressHook = null;
12965
13138
  nextWorkInProgressHook = null;
12966
13139
 
12967
- remainingExpirationTime = NoWork;
12968
- componentUpdateQueue = null;
12969
- sideEffectTag = 0;
12970
-
12971
13140
  {
13141
+ hookTypesDev = null;
13142
+ hookTypesUpdateIndexDev = -1;
13143
+
12972
13144
  currentHookNameInDev = null;
12973
13145
  }
12974
13146
 
13147
+ remainingExpirationTime = NoWork;
13148
+ componentUpdateQueue = null;
13149
+ sideEffectTag = 0;
13150
+
12975
13151
  didScheduleRenderPhaseUpdate = false;
12976
13152
  renderPhaseUpdates = null;
12977
13153
  numberOfReRenders = 0;
@@ -12988,12 +13164,6 @@ function mountWorkInProgressHook() {
12988
13164
  next: null
12989
13165
  };
12990
13166
 
12991
- {
12992
- hook._debugType = currentHookNameInDev;
12993
- if (currentlyRenderingFiber$1 !== null && currentlyRenderingFiber$1.alternate !== null) {
12994
- 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));
12995
- }
12996
- }
12997
13167
  if (workInProgressHook === null) {
12998
13168
  // This is the first hook in the list
12999
13169
  firstWorkInProgressHook = workInProgressHook = hook;
@@ -13040,13 +13210,6 @@ function updateWorkInProgressHook() {
13040
13210
  workInProgressHook = workInProgressHook.next = newHook;
13041
13211
  }
13042
13212
  nextCurrentHook = currentHook.next;
13043
-
13044
- {
13045
- newHook._debugType = currentHookNameInDev;
13046
- if (currentHookNameInDev !== currentHook._debugType) {
13047
- warnOnHookMismatchInDev();
13048
- }
13049
- }
13050
13213
  }
13051
13214
  return workInProgressHook;
13052
13215
  }
@@ -13061,20 +13224,6 @@ function basicStateReducer(state, action) {
13061
13224
  return typeof action === 'function' ? action(state) : action;
13062
13225
  }
13063
13226
 
13064
- function mountContext(context, observedBits) {
13065
- {
13066
- mountWorkInProgressHook();
13067
- }
13068
- return readContext(context, observedBits);
13069
- }
13070
-
13071
- function updateContext(context, observedBits) {
13072
- {
13073
- updateWorkInProgressHook();
13074
- }
13075
- return readContext(context, observedBits);
13076
- }
13077
-
13078
13227
  function mountReducer(reducer, initialArg, init) {
13079
13228
  var hook = mountWorkInProgressHook();
13080
13229
  var initialState = void 0;
@@ -13127,7 +13276,6 @@ function updateReducer(reducer, initialArg, init) {
13127
13276
  }
13128
13277
 
13129
13278
  hook.memoizedState = newState;
13130
-
13131
13279
  // Don't persist the state accumlated from the render phase updates to
13132
13280
  // the base state unless the queue is empty.
13133
13281
  // TODO: Not sure if this is the desired semantics, but it's what we
@@ -13136,6 +13284,9 @@ function updateReducer(reducer, initialArg, init) {
13136
13284
  hook.baseState = newState;
13137
13285
  }
13138
13286
 
13287
+ queue.eagerReducer = reducer;
13288
+ queue.eagerState = newState;
13289
+
13139
13290
  return [newState, _dispatch];
13140
13291
  }
13141
13292
  }
@@ -13355,7 +13506,7 @@ function mountImperativeHandle(ref, create, deps) {
13355
13506
  }
13356
13507
 
13357
13508
  // TODO: If deps are provided, should we skip comparing the ref itself?
13358
- var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : [ref];
13509
+ var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
13359
13510
 
13360
13511
  return mountEffectImpl(Update, UnmountMutation | MountLayout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
13361
13512
  }
@@ -13366,7 +13517,7 @@ function updateImperativeHandle(ref, create, deps) {
13366
13517
  }
13367
13518
 
13368
13519
  // TODO: If deps are provided, should we skip comparing the ref itself?
13369
- var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : [ref];
13520
+ var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
13370
13521
 
13371
13522
  return updateEffectImpl(Update, UnmountMutation | MountLayout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
13372
13523
  }
@@ -13433,7 +13584,7 @@ function updateMemo(nextCreate, deps) {
13433
13584
  var shouldWarnForUnbatchedSetState = false;
13434
13585
 
13435
13586
  {
13436
- // jest isnt' a 'global', it's just exposed to tests via a wrapped function
13587
+ // jest isn't a 'global', it's just exposed to tests via a wrapped function
13437
13588
  // further, this isn't a test file, so flow doesn't recognize the symbol. So...
13438
13589
  // $FlowExpectedError - because requirements don't give a damn about your type sigs.
13439
13590
  if ('undefined' !== typeof jest) {
@@ -13565,6 +13716,7 @@ var ContextOnlyDispatcher = {
13565
13716
  };
13566
13717
 
13567
13718
  var HooksDispatcherOnMountInDEV = null;
13719
+ var HooksDispatcherOnMountWithHookTypesInDEV = null;
13568
13720
  var HooksDispatcherOnUpdateInDEV = null;
13569
13721
  var InvalidNestedHooksDispatcherOnMountInDEV = null;
13570
13722
  var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
@@ -13584,26 +13736,106 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
13584
13736
  },
13585
13737
  useCallback: function (callback, deps) {
13586
13738
  currentHookNameInDev = 'useCallback';
13739
+ mountHookTypesDev();
13740
+ return mountCallback(callback, deps);
13741
+ },
13742
+ useContext: function (context, observedBits) {
13743
+ currentHookNameInDev = 'useContext';
13744
+ mountHookTypesDev();
13745
+ return readContext(context, observedBits);
13746
+ },
13747
+ useEffect: function (create, deps) {
13748
+ currentHookNameInDev = 'useEffect';
13749
+ mountHookTypesDev();
13750
+ return mountEffect(create, deps);
13751
+ },
13752
+ useImperativeHandle: function (ref, create, deps) {
13753
+ currentHookNameInDev = 'useImperativeHandle';
13754
+ mountHookTypesDev();
13755
+ return mountImperativeHandle(ref, create, deps);
13756
+ },
13757
+ useLayoutEffect: function (create, deps) {
13758
+ currentHookNameInDev = 'useLayoutEffect';
13759
+ mountHookTypesDev();
13760
+ return mountLayoutEffect(create, deps);
13761
+ },
13762
+ useMemo: function (create, deps) {
13763
+ currentHookNameInDev = 'useMemo';
13764
+ mountHookTypesDev();
13765
+ var prevDispatcher = ReactCurrentDispatcher$1.current;
13766
+ ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
13767
+ try {
13768
+ return mountMemo(create, deps);
13769
+ } finally {
13770
+ ReactCurrentDispatcher$1.current = prevDispatcher;
13771
+ }
13772
+ },
13773
+ useReducer: function (reducer, initialArg, init) {
13774
+ currentHookNameInDev = 'useReducer';
13775
+ mountHookTypesDev();
13776
+ var prevDispatcher = ReactCurrentDispatcher$1.current;
13777
+ ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
13778
+ try {
13779
+ return mountReducer(reducer, initialArg, init);
13780
+ } finally {
13781
+ ReactCurrentDispatcher$1.current = prevDispatcher;
13782
+ }
13783
+ },
13784
+ useRef: function (initialValue) {
13785
+ currentHookNameInDev = 'useRef';
13786
+ mountHookTypesDev();
13787
+ return mountRef(initialValue);
13788
+ },
13789
+ useState: function (initialState) {
13790
+ currentHookNameInDev = 'useState';
13791
+ mountHookTypesDev();
13792
+ var prevDispatcher = ReactCurrentDispatcher$1.current;
13793
+ ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
13794
+ try {
13795
+ return mountState(initialState);
13796
+ } finally {
13797
+ ReactCurrentDispatcher$1.current = prevDispatcher;
13798
+ }
13799
+ },
13800
+ useDebugValue: function (value, formatterFn) {
13801
+ currentHookNameInDev = 'useDebugValue';
13802
+ mountHookTypesDev();
13803
+ return mountDebugValue(value, formatterFn);
13804
+ }
13805
+ };
13806
+
13807
+ HooksDispatcherOnMountWithHookTypesInDEV = {
13808
+ readContext: function (context, observedBits) {
13809
+ return readContext(context, observedBits);
13810
+ },
13811
+ useCallback: function (callback, deps) {
13812
+ currentHookNameInDev = 'useCallback';
13813
+ updateHookTypesDev();
13587
13814
  return mountCallback(callback, deps);
13588
13815
  },
13589
13816
  useContext: function (context, observedBits) {
13590
13817
  currentHookNameInDev = 'useContext';
13591
- return mountContext(context, observedBits);
13818
+ updateHookTypesDev();
13819
+ return readContext(context, observedBits);
13592
13820
  },
13593
13821
  useEffect: function (create, deps) {
13594
13822
  currentHookNameInDev = 'useEffect';
13823
+ updateHookTypesDev();
13595
13824
  return mountEffect(create, deps);
13596
13825
  },
13597
13826
  useImperativeHandle: function (ref, create, deps) {
13598
13827
  currentHookNameInDev = 'useImperativeHandle';
13828
+ updateHookTypesDev();
13599
13829
  return mountImperativeHandle(ref, create, deps);
13600
13830
  },
13601
13831
  useLayoutEffect: function (create, deps) {
13602
13832
  currentHookNameInDev = 'useLayoutEffect';
13833
+ updateHookTypesDev();
13603
13834
  return mountLayoutEffect(create, deps);
13604
13835
  },
13605
13836
  useMemo: function (create, deps) {
13606
13837
  currentHookNameInDev = 'useMemo';
13838
+ updateHookTypesDev();
13607
13839
  var prevDispatcher = ReactCurrentDispatcher$1.current;
13608
13840
  ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
13609
13841
  try {
@@ -13614,6 +13846,7 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
13614
13846
  },
13615
13847
  useReducer: function (reducer, initialArg, init) {
13616
13848
  currentHookNameInDev = 'useReducer';
13849
+ updateHookTypesDev();
13617
13850
  var prevDispatcher = ReactCurrentDispatcher$1.current;
13618
13851
  ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
13619
13852
  try {
@@ -13624,10 +13857,12 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
13624
13857
  },
13625
13858
  useRef: function (initialValue) {
13626
13859
  currentHookNameInDev = 'useRef';
13860
+ updateHookTypesDev();
13627
13861
  return mountRef(initialValue);
13628
13862
  },
13629
13863
  useState: function (initialState) {
13630
13864
  currentHookNameInDev = 'useState';
13865
+ updateHookTypesDev();
13631
13866
  var prevDispatcher = ReactCurrentDispatcher$1.current;
13632
13867
  ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
13633
13868
  try {
@@ -13638,6 +13873,7 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
13638
13873
  },
13639
13874
  useDebugValue: function (value, formatterFn) {
13640
13875
  currentHookNameInDev = 'useDebugValue';
13876
+ updateHookTypesDev();
13641
13877
  return mountDebugValue(value, formatterFn);
13642
13878
  }
13643
13879
  };
@@ -13648,26 +13884,32 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
13648
13884
  },
13649
13885
  useCallback: function (callback, deps) {
13650
13886
  currentHookNameInDev = 'useCallback';
13887
+ updateHookTypesDev();
13651
13888
  return updateCallback(callback, deps);
13652
13889
  },
13653
13890
  useContext: function (context, observedBits) {
13654
13891
  currentHookNameInDev = 'useContext';
13655
- return updateContext(context, observedBits);
13892
+ updateHookTypesDev();
13893
+ return readContext(context, observedBits);
13656
13894
  },
13657
13895
  useEffect: function (create, deps) {
13658
13896
  currentHookNameInDev = 'useEffect';
13897
+ updateHookTypesDev();
13659
13898
  return updateEffect(create, deps);
13660
13899
  },
13661
13900
  useImperativeHandle: function (ref, create, deps) {
13662
13901
  currentHookNameInDev = 'useImperativeHandle';
13902
+ updateHookTypesDev();
13663
13903
  return updateImperativeHandle(ref, create, deps);
13664
13904
  },
13665
13905
  useLayoutEffect: function (create, deps) {
13666
13906
  currentHookNameInDev = 'useLayoutEffect';
13907
+ updateHookTypesDev();
13667
13908
  return updateLayoutEffect(create, deps);
13668
13909
  },
13669
13910
  useMemo: function (create, deps) {
13670
13911
  currentHookNameInDev = 'useMemo';
13912
+ updateHookTypesDev();
13671
13913
  var prevDispatcher = ReactCurrentDispatcher$1.current;
13672
13914
  ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
13673
13915
  try {
@@ -13678,6 +13920,7 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
13678
13920
  },
13679
13921
  useReducer: function (reducer, initialArg, init) {
13680
13922
  currentHookNameInDev = 'useReducer';
13923
+ updateHookTypesDev();
13681
13924
  var prevDispatcher = ReactCurrentDispatcher$1.current;
13682
13925
  ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
13683
13926
  try {
@@ -13688,10 +13931,12 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
13688
13931
  },
13689
13932
  useRef: function (initialValue) {
13690
13933
  currentHookNameInDev = 'useRef';
13934
+ updateHookTypesDev();
13691
13935
  return updateRef(initialValue);
13692
13936
  },
13693
13937
  useState: function (initialState) {
13694
13938
  currentHookNameInDev = 'useState';
13939
+ updateHookTypesDev();
13695
13940
  var prevDispatcher = ReactCurrentDispatcher$1.current;
13696
13941
  ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
13697
13942
  try {
@@ -13702,6 +13947,7 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
13702
13947
  },
13703
13948
  useDebugValue: function (value, formatterFn) {
13704
13949
  currentHookNameInDev = 'useDebugValue';
13950
+ updateHookTypesDev();
13705
13951
  return updateDebugValue(value, formatterFn);
13706
13952
  }
13707
13953
  };
@@ -13714,31 +13960,37 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
13714
13960
  useCallback: function (callback, deps) {
13715
13961
  currentHookNameInDev = 'useCallback';
13716
13962
  warnInvalidHookAccess();
13963
+ mountHookTypesDev();
13717
13964
  return mountCallback(callback, deps);
13718
13965
  },
13719
13966
  useContext: function (context, observedBits) {
13720
13967
  currentHookNameInDev = 'useContext';
13721
13968
  warnInvalidHookAccess();
13722
- return mountContext(context, observedBits);
13969
+ mountHookTypesDev();
13970
+ return readContext(context, observedBits);
13723
13971
  },
13724
13972
  useEffect: function (create, deps) {
13725
13973
  currentHookNameInDev = 'useEffect';
13726
13974
  warnInvalidHookAccess();
13975
+ mountHookTypesDev();
13727
13976
  return mountEffect(create, deps);
13728
13977
  },
13729
13978
  useImperativeHandle: function (ref, create, deps) {
13730
13979
  currentHookNameInDev = 'useImperativeHandle';
13731
13980
  warnInvalidHookAccess();
13981
+ mountHookTypesDev();
13732
13982
  return mountImperativeHandle(ref, create, deps);
13733
13983
  },
13734
13984
  useLayoutEffect: function (create, deps) {
13735
13985
  currentHookNameInDev = 'useLayoutEffect';
13736
13986
  warnInvalidHookAccess();
13987
+ mountHookTypesDev();
13737
13988
  return mountLayoutEffect(create, deps);
13738
13989
  },
13739
13990
  useMemo: function (create, deps) {
13740
13991
  currentHookNameInDev = 'useMemo';
13741
13992
  warnInvalidHookAccess();
13993
+ mountHookTypesDev();
13742
13994
  var prevDispatcher = ReactCurrentDispatcher$1.current;
13743
13995
  ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
13744
13996
  try {
@@ -13750,6 +14002,7 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
13750
14002
  useReducer: function (reducer, initialArg, init) {
13751
14003
  currentHookNameInDev = 'useReducer';
13752
14004
  warnInvalidHookAccess();
14005
+ mountHookTypesDev();
13753
14006
  var prevDispatcher = ReactCurrentDispatcher$1.current;
13754
14007
  ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
13755
14008
  try {
@@ -13761,11 +14014,13 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
13761
14014
  useRef: function (initialValue) {
13762
14015
  currentHookNameInDev = 'useRef';
13763
14016
  warnInvalidHookAccess();
14017
+ mountHookTypesDev();
13764
14018
  return mountRef(initialValue);
13765
14019
  },
13766
14020
  useState: function (initialState) {
13767
14021
  currentHookNameInDev = 'useState';
13768
14022
  warnInvalidHookAccess();
14023
+ mountHookTypesDev();
13769
14024
  var prevDispatcher = ReactCurrentDispatcher$1.current;
13770
14025
  ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
13771
14026
  try {
@@ -13777,6 +14032,7 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
13777
14032
  useDebugValue: function (value, formatterFn) {
13778
14033
  currentHookNameInDev = 'useDebugValue';
13779
14034
  warnInvalidHookAccess();
14035
+ mountHookTypesDev();
13780
14036
  return mountDebugValue(value, formatterFn);
13781
14037
  }
13782
14038
  };
@@ -13789,31 +14045,37 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
13789
14045
  useCallback: function (callback, deps) {
13790
14046
  currentHookNameInDev = 'useCallback';
13791
14047
  warnInvalidHookAccess();
14048
+ updateHookTypesDev();
13792
14049
  return updateCallback(callback, deps);
13793
14050
  },
13794
14051
  useContext: function (context, observedBits) {
13795
14052
  currentHookNameInDev = 'useContext';
13796
14053
  warnInvalidHookAccess();
13797
- return updateContext(context, observedBits);
14054
+ updateHookTypesDev();
14055
+ return readContext(context, observedBits);
13798
14056
  },
13799
14057
  useEffect: function (create, deps) {
13800
14058
  currentHookNameInDev = 'useEffect';
13801
14059
  warnInvalidHookAccess();
14060
+ updateHookTypesDev();
13802
14061
  return updateEffect(create, deps);
13803
14062
  },
13804
14063
  useImperativeHandle: function (ref, create, deps) {
13805
14064
  currentHookNameInDev = 'useImperativeHandle';
13806
14065
  warnInvalidHookAccess();
14066
+ updateHookTypesDev();
13807
14067
  return updateImperativeHandle(ref, create, deps);
13808
14068
  },
13809
14069
  useLayoutEffect: function (create, deps) {
13810
14070
  currentHookNameInDev = 'useLayoutEffect';
13811
14071
  warnInvalidHookAccess();
14072
+ updateHookTypesDev();
13812
14073
  return updateLayoutEffect(create, deps);
13813
14074
  },
13814
14075
  useMemo: function (create, deps) {
13815
14076
  currentHookNameInDev = 'useMemo';
13816
14077
  warnInvalidHookAccess();
14078
+ updateHookTypesDev();
13817
14079
  var prevDispatcher = ReactCurrentDispatcher$1.current;
13818
14080
  ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
13819
14081
  try {
@@ -13825,6 +14087,7 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
13825
14087
  useReducer: function (reducer, initialArg, init) {
13826
14088
  currentHookNameInDev = 'useReducer';
13827
14089
  warnInvalidHookAccess();
14090
+ updateHookTypesDev();
13828
14091
  var prevDispatcher = ReactCurrentDispatcher$1.current;
13829
14092
  ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
13830
14093
  try {
@@ -13836,11 +14099,13 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
13836
14099
  useRef: function (initialValue) {
13837
14100
  currentHookNameInDev = 'useRef';
13838
14101
  warnInvalidHookAccess();
14102
+ updateHookTypesDev();
13839
14103
  return updateRef(initialValue);
13840
14104
  },
13841
14105
  useState: function (initialState) {
13842
14106
  currentHookNameInDev = 'useState';
13843
14107
  warnInvalidHookAccess();
14108
+ updateHookTypesDev();
13844
14109
  var prevDispatcher = ReactCurrentDispatcher$1.current;
13845
14110
  ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
13846
14111
  try {
@@ -13852,6 +14117,7 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
13852
14117
  useDebugValue: function (value, formatterFn) {
13853
14118
  currentHookNameInDev = 'useDebugValue';
13854
14119
  warnInvalidHookAccess();
14120
+ updateHookTypesDev();
13855
14121
  return updateDebugValue(value, formatterFn);
13856
14122
  }
13857
14123
  };
@@ -13923,6 +14189,18 @@ function enterHydrationState(fiber) {
13923
14189
  return true;
13924
14190
  }
13925
14191
 
14192
+ function reenterHydrationStateFromDehydratedSuspenseInstance(fiber) {
14193
+ if (!supportsHydration) {
14194
+ return false;
14195
+ }
14196
+
14197
+ var suspenseInstance = fiber.stateNode;
14198
+ nextHydratableInstance = getNextHydratableSibling(suspenseInstance);
14199
+ popToNextHostParent(fiber);
14200
+ isHydrating = true;
14201
+ return true;
14202
+ }
14203
+
13926
14204
  function deleteHydratableInstance(returnFiber, instance) {
13927
14205
  {
13928
14206
  switch (returnFiber.tag) {
@@ -13969,6 +14247,9 @@ function insertNonHydratedInstance(returnFiber, fiber) {
13969
14247
  case HostText:
13970
14248
  var text = fiber.pendingProps;
13971
14249
  didNotFindHydratableContainerTextInstance(parentContainer, text);
14250
+ break;
14251
+ case SuspenseComponent:
14252
+
13972
14253
  break;
13973
14254
  }
13974
14255
  break;
@@ -13988,6 +14269,9 @@ function insertNonHydratedInstance(returnFiber, fiber) {
13988
14269
  var _text = fiber.pendingProps;
13989
14270
  didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, _text);
13990
14271
  break;
14272
+ case SuspenseComponent:
14273
+ didNotFindHydratableSuspenseInstance(parentType, parentProps, parentInstance);
14274
+ break;
13991
14275
  }
13992
14276
  break;
13993
14277
  }
@@ -14020,6 +14304,19 @@ function tryHydrate(fiber, nextInstance) {
14020
14304
  }
14021
14305
  return false;
14022
14306
  }
14307
+ case SuspenseComponent:
14308
+ {
14309
+ if (enableSuspenseServerRenderer) {
14310
+ var suspenseInstance = canHydrateSuspenseInstance(nextInstance);
14311
+ if (suspenseInstance !== null) {
14312
+ // Downgrade the tag to a dehydrated component until we've hydrated it.
14313
+ fiber.tag = DehydratedSuspenseComponent;
14314
+ fiber.stateNode = suspenseInstance;
14315
+ return true;
14316
+ }
14317
+ }
14318
+ return false;
14319
+ }
14023
14320
  default:
14024
14321
  return false;
14025
14322
  }
@@ -14113,9 +14410,18 @@ function prepareToHydrateHostTextInstance(fiber) {
14113
14410
  return shouldUpdate;
14114
14411
  }
14115
14412
 
14413
+ function skipPastDehydratedSuspenseInstance(fiber) {
14414
+ if (!supportsHydration) {
14415
+ invariant(false, 'Expected skipPastDehydratedSuspenseInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.');
14416
+ }
14417
+ var suspenseInstance = fiber.stateNode;
14418
+ !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;
14419
+ nextHydratableInstance = getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance);
14420
+ }
14421
+
14116
14422
  function popToNextHostParent(fiber) {
14117
14423
  var parent = fiber.return;
14118
- while (parent !== null && parent.tag !== HostComponent && parent.tag !== HostRoot) {
14424
+ while (parent !== null && parent.tag !== HostComponent && parent.tag !== HostRoot && parent.tag !== DehydratedSuspenseComponent) {
14119
14425
  parent = parent.return;
14120
14426
  }
14121
14427
  hydrationParentFiber = parent;
@@ -14223,6 +14529,10 @@ function forceUnmountCurrentAndReconcile(current$$1, workInProgress, nextChildre
14223
14529
  }
14224
14530
 
14225
14531
  function updateForwardRef(current$$1, workInProgress, Component, nextProps, renderExpirationTime) {
14532
+ // TODO: current can be non-null here even if the component
14533
+ // hasn't yet mounted. This happens after the first render suspends.
14534
+ // We'll need to figure out if this is fine or can cause issues.
14535
+
14226
14536
  {
14227
14537
  if (workInProgress.type !== workInProgress.elementType) {
14228
14538
  // Lazy component props can't be validated in createElement
@@ -14328,6 +14638,10 @@ function updateMemoComponent(current$$1, workInProgress, Component, nextProps, u
14328
14638
  }
14329
14639
 
14330
14640
  function updateSimpleMemoComponent(current$$1, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
14641
+ // TODO: current can be non-null here even if the component
14642
+ // hasn't yet mounted. This happens when the inner render suspends.
14643
+ // We'll need to figure out if this is fine or can cause issues.
14644
+
14331
14645
  {
14332
14646
  if (workInProgress.type !== workInProgress.elementType) {
14333
14647
  // Lazy component props can't be validated in createElement
@@ -14951,6 +15265,18 @@ function updateSuspenseComponent(current$$1, workInProgress, renderExpirationTim
14951
15265
  // children -- we skip over the primary children entirely.
14952
15266
  var next = void 0;
14953
15267
  if (current$$1 === null) {
15268
+ if (enableSuspenseServerRenderer) {
15269
+ // If we're currently hydrating, try to hydrate this boundary.
15270
+ // But only if this has a fallback.
15271
+ if (nextProps.fallback !== undefined) {
15272
+ tryToClaimNextHydratableInstance(workInProgress);
15273
+ // This could've changed the tag if this was a dehydrated suspense component.
15274
+ if (workInProgress.tag === DehydratedSuspenseComponent) {
15275
+ return updateDehydratedSuspenseComponent(null, workInProgress, renderExpirationTime);
15276
+ }
15277
+ }
15278
+ }
15279
+
14954
15280
  // This is the initial mount. This branch is pretty simple because there's
14955
15281
  // no previous state that needs to be preserved.
14956
15282
  if (nextDidTimeout) {
@@ -15102,6 +15428,65 @@ function updateSuspenseComponent(current$$1, workInProgress, renderExpirationTim
15102
15428
  return next;
15103
15429
  }
15104
15430
 
15431
+ function updateDehydratedSuspenseComponent(current$$1, workInProgress, renderExpirationTime) {
15432
+ if (current$$1 === null) {
15433
+ // During the first pass, we'll bail out and not drill into the children.
15434
+ // Instead, we'll leave the content in place and try to hydrate it later.
15435
+ workInProgress.expirationTime = Never;
15436
+ return null;
15437
+ }
15438
+ // We use childExpirationTime to indicate that a child might depend on context, so if
15439
+ // any context has changed, we need to treat is as if the input might have changed.
15440
+ var hasContextChanged$$1 = current$$1.childExpirationTime >= renderExpirationTime;
15441
+ if (didReceiveUpdate || hasContextChanged$$1) {
15442
+ // This boundary has changed since the first render. This means that we are now unable to
15443
+ // hydrate it. We might still be able to hydrate it using an earlier expiration time but
15444
+ // during this render we can't. Instead, we're going to delete the whole subtree and
15445
+ // instead inject a new real Suspense boundary to take its place, which may render content
15446
+ // or fallback. The real Suspense boundary will suspend for a while so we have some time
15447
+ // to ensure it can produce real content, but all state and pending events will be lost.
15448
+
15449
+ // Detach from the current dehydrated boundary.
15450
+ current$$1.alternate = null;
15451
+ workInProgress.alternate = null;
15452
+
15453
+ // Insert a deletion in the effect list.
15454
+ var returnFiber = workInProgress.return;
15455
+ !(returnFiber !== null) ? invariant(false, 'Suspense boundaries are never on the root. This is probably a bug in React.') : void 0;
15456
+ var last = returnFiber.lastEffect;
15457
+ if (last !== null) {
15458
+ last.nextEffect = current$$1;
15459
+ returnFiber.lastEffect = current$$1;
15460
+ } else {
15461
+ returnFiber.firstEffect = returnFiber.lastEffect = current$$1;
15462
+ }
15463
+ current$$1.nextEffect = null;
15464
+ current$$1.effectTag = Deletion;
15465
+
15466
+ // Upgrade this work in progress to a real Suspense component.
15467
+ workInProgress.tag = SuspenseComponent;
15468
+ workInProgress.stateNode = null;
15469
+ workInProgress.memoizedState = null;
15470
+ // This is now an insertion.
15471
+ workInProgress.effectTag |= Placement;
15472
+ // Retry as a real Suspense component.
15473
+ return updateSuspenseComponent(null, workInProgress, renderExpirationTime);
15474
+ }
15475
+ if ((workInProgress.effectTag & DidCapture) === NoEffect) {
15476
+ // This is the first attempt.
15477
+ reenterHydrationStateFromDehydratedSuspenseInstance(workInProgress);
15478
+ var nextProps = workInProgress.pendingProps;
15479
+ var nextChildren = nextProps.children;
15480
+ workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
15481
+ return workInProgress.child;
15482
+ } else {
15483
+ // Something suspended. Leave the existing children in place.
15484
+ // TODO: In non-concurrent mode, should we commit the nodes we have hydrated so far?
15485
+ workInProgress.child = null;
15486
+ return null;
15487
+ }
15488
+ }
15489
+
15105
15490
  function updatePortalComponent(current$$1, workInProgress, renderExpirationTime) {
15106
15491
  pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
15107
15492
  var nextChildren = workInProgress.pendingProps;
@@ -15313,6 +15698,16 @@ function beginWork(current$$1, workInProgress, renderExpirationTime) {
15313
15698
  }
15314
15699
  break;
15315
15700
  }
15701
+ case DehydratedSuspenseComponent:
15702
+ {
15703
+ if (enableSuspenseServerRenderer) {
15704
+ // We know that this component will suspend again because if it has
15705
+ // been unsuspended it has committed as a regular Suspense component.
15706
+ // If it needs to be retried, it should have work scheduled on it.
15707
+ workInProgress.effectTag |= DidCapture;
15708
+ break;
15709
+ }
15710
+ }
15316
15711
  }
15317
15712
  return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
15318
15713
  }
@@ -15404,9 +15799,15 @@ function beginWork(current$$1, workInProgress, renderExpirationTime) {
15404
15799
  var _resolvedProps4 = workInProgress.elementType === _Component3 ? _unresolvedProps4 : resolveDefaultProps(_Component3, _unresolvedProps4);
15405
15800
  return mountIncompleteClassComponent(current$$1, workInProgress, _Component3, _resolvedProps4, renderExpirationTime);
15406
15801
  }
15407
- default:
15408
- invariant(false, 'Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.');
15802
+ case DehydratedSuspenseComponent:
15803
+ {
15804
+ if (enableSuspenseServerRenderer) {
15805
+ return updateDehydratedSuspenseComponent(current$$1, workInProgress, renderExpirationTime);
15806
+ }
15807
+ break;
15808
+ }
15409
15809
  }
15810
+ invariant(false, 'Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.');
15410
15811
  }
15411
15812
 
15412
15813
  var valueCursor = createCursor(null);
@@ -15495,6 +15896,28 @@ function calculateChangedBits(context, newValue, oldValue) {
15495
15896
  }
15496
15897
  }
15497
15898
 
15899
+ function scheduleWorkOnParentPath(parent, renderExpirationTime) {
15900
+ // Update the child expiration time of all the ancestors, including
15901
+ // the alternates.
15902
+ var node = parent;
15903
+ while (node !== null) {
15904
+ var alternate = node.alternate;
15905
+ if (node.childExpirationTime < renderExpirationTime) {
15906
+ node.childExpirationTime = renderExpirationTime;
15907
+ if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
15908
+ alternate.childExpirationTime = renderExpirationTime;
15909
+ }
15910
+ } else if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
15911
+ alternate.childExpirationTime = renderExpirationTime;
15912
+ } else {
15913
+ // Neither alternate was updated, which means the rest of the
15914
+ // ancestor path already has sufficient priority.
15915
+ break;
15916
+ }
15917
+ node = node.return;
15918
+ }
15919
+ }
15920
+
15498
15921
  function propagateContextChange(workInProgress, context, changedBits, renderExpirationTime) {
15499
15922
  var fiber = workInProgress.child;
15500
15923
  if (fiber !== null) {
@@ -15533,25 +15956,8 @@ function propagateContextChange(workInProgress, context, changedBits, renderExpi
15533
15956
  if (alternate !== null && alternate.expirationTime < renderExpirationTime) {
15534
15957
  alternate.expirationTime = renderExpirationTime;
15535
15958
  }
15536
- // Update the child expiration time of all the ancestors, including
15537
- // the alternates.
15538
- var node = fiber.return;
15539
- while (node !== null) {
15540
- alternate = node.alternate;
15541
- if (node.childExpirationTime < renderExpirationTime) {
15542
- node.childExpirationTime = renderExpirationTime;
15543
- if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
15544
- alternate.childExpirationTime = renderExpirationTime;
15545
- }
15546
- } else if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
15547
- alternate.childExpirationTime = renderExpirationTime;
15548
- } else {
15549
- // Neither alternate was updated, which means the rest of the
15550
- // ancestor path already has sufficient priority.
15551
- break;
15552
- }
15553
- node = node.return;
15554
- }
15959
+
15960
+ scheduleWorkOnParentPath(fiber.return, renderExpirationTime);
15555
15961
 
15556
15962
  // Mark the expiration time on the list, too.
15557
15963
  if (list.expirationTime < renderExpirationTime) {
@@ -15567,6 +15973,23 @@ function propagateContextChange(workInProgress, context, changedBits, renderExpi
15567
15973
  } else if (fiber.tag === ContextProvider) {
15568
15974
  // Don't scan deeper if this is a matching provider
15569
15975
  nextFiber = fiber.type === workInProgress.type ? null : fiber.child;
15976
+ } else if (enableSuspenseServerRenderer && fiber.tag === DehydratedSuspenseComponent) {
15977
+ // If a dehydrated suspense component is in this subtree, we don't know
15978
+ // if it will have any context consumers in it. The best we can do is
15979
+ // mark it as having updates on its children.
15980
+ if (fiber.expirationTime < renderExpirationTime) {
15981
+ fiber.expirationTime = renderExpirationTime;
15982
+ }
15983
+ var _alternate = fiber.alternate;
15984
+ if (_alternate !== null && _alternate.expirationTime < renderExpirationTime) {
15985
+ _alternate.expirationTime = renderExpirationTime;
15986
+ }
15987
+ // This is intentionally passing this fiber as the parent
15988
+ // because we want to schedule this fiber as having work
15989
+ // on its children. We'll use the childExpirationTime on
15990
+ // this fiber to indicate that a context has changed.
15991
+ scheduleWorkOnParentPath(fiber, renderExpirationTime);
15992
+ nextFiber = fiber.sibling;
15570
15993
  } else {
15571
15994
  // Traverse down.
15572
15995
  nextFiber = fiber.child;
@@ -16690,6 +17113,26 @@ function completeWork(current, workInProgress, renderExpirationTime) {
16690
17113
  }
16691
17114
  break;
16692
17115
  }
17116
+ case DehydratedSuspenseComponent:
17117
+ {
17118
+ if (enableSuspenseServerRenderer) {
17119
+ if (current === null) {
17120
+ var _wasHydrated2 = popHydrationState(workInProgress);
17121
+ !_wasHydrated2 ? invariant(false, 'A dehydrated suspense component was completed without a hydrated node. This is probably a bug in React.') : void 0;
17122
+ skipPastDehydratedSuspenseInstance(workInProgress);
17123
+ } else if ((workInProgress.effectTag & DidCapture) === NoEffect) {
17124
+ // This boundary did not suspend so it's now hydrated.
17125
+ // To handle any future suspense cases, we're going to now upgrade it
17126
+ // to a Suspense component. We detach it from the existing current fiber.
17127
+ current.alternate = null;
17128
+ workInProgress.alternate = null;
17129
+ workInProgress.tag = SuspenseComponent;
17130
+ workInProgress.memoizedState = null;
17131
+ workInProgress.stateNode = null;
17132
+ }
17133
+ }
17134
+ break;
17135
+ }
16693
17136
  default:
16694
17137
  invariant(false, 'Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.');
16695
17138
  }
@@ -16780,7 +17223,7 @@ var didWarnAboutUndefinedSnapshotBeforeUpdate = null;
16780
17223
  didWarnAboutUndefinedSnapshotBeforeUpdate = new Set();
16781
17224
  }
16782
17225
 
16783
- var PossiblyWeakSet = typeof WeakSet === 'function' ? WeakSet : Set;
17226
+ var PossiblyWeakSet$1 = typeof WeakSet === 'function' ? WeakSet : Set;
16784
17227
 
16785
17228
  function logError(boundary, errorInfo) {
16786
17229
  var source = errorInfo.source;
@@ -16946,11 +17389,11 @@ function commitHookEffectList(unmountTag, mountTag, finishedWork) {
16946
17389
  if (_destroy === null) {
16947
17390
  addendum = ' You returned null. If your effect does not require clean ' + 'up, return undefined (or nothing).';
16948
17391
  } else if (typeof _destroy.then === 'function') {
16949
- addendum = '\n\nIt looks like you wrote useEffect(async () => ...) or returned a Promise. ' + 'Instead, you may write an async function separately ' + 'and then call it from inside the effect:\n\n' + 'async function fetchComment(commentId) {\n' + ' // You can await here\n' + '}\n\n' + 'useEffect(() => {\n' + ' fetchComment(commentId);\n' + '}, [commentId]);\n\n' + 'In the future, React will provide a more idiomatic solution for data fetching ' + "that doesn't involve writing effects manually.";
17392
+ addendum = '\n\nIt looks like you wrote useEffect(async () => ...) or returned a Promise. ' + 'Instead, write the async function inside your effect ' + 'and call it immediately:\n\n' + 'useEffect(() => {\n' + ' async function fetchData() {\n' + ' // You can await here\n' + ' const response = await MyAPI.getData(someId);\n' + ' // ...\n' + ' }\n' + ' fetchData();\n' + '}, [someId]); // Or [] if effect doesn\'t need props or state\n\n' + 'Learn more about data fetching with Hooks: https://fb.me/react-hooks-data-fetching';
16950
17393
  } else {
16951
17394
  addendum = ' You returned: ' + _destroy;
16952
17395
  }
16953
- warningWithoutStack$1(false, 'An Effect function must not return anything besides a function, ' + 'which is used for clean-up.%s%s', addendum, getStackByFiberInDevAndProd(finishedWork));
17396
+ warningWithoutStack$1(false, 'An effect function must not return anything besides a function, ' + 'which is used for clean-up.%s%s', addendum, getStackByFiberInDevAndProd(finishedWork));
16954
17397
  }
16955
17398
  }
16956
17399
  }
@@ -17093,7 +17536,7 @@ function commitLifeCycles(finishedRoot, current$$1, finishedWork, committedExpir
17093
17536
 
17094
17537
  function hideOrUnhideAllChildren(finishedWork, isHidden) {
17095
17538
  if (supportsMutation) {
17096
- // We only have the top Fiber that was inserted but we need recurse down its
17539
+ // We only have the top Fiber that was inserted but we need to recurse down its
17097
17540
  var node = finishedWork;
17098
17541
  while (true) {
17099
17542
  if (node.tag === HostComponent) {
@@ -17361,7 +17804,7 @@ function getHostSibling(fiber) {
17361
17804
  }
17362
17805
  node.sibling.return = node.return;
17363
17806
  node = node.sibling;
17364
- while (node.tag !== HostComponent && node.tag !== HostText) {
17807
+ while (node.tag !== HostComponent && node.tag !== HostText && node.tag !== DehydratedSuspenseComponent) {
17365
17808
  // If it is not host node and, we might have a host node inside it.
17366
17809
  // Try to search down until we find one.
17367
17810
  if (node.effectTag & Placement) {
@@ -17421,7 +17864,7 @@ function commitPlacement(finishedWork) {
17421
17864
  }
17422
17865
 
17423
17866
  var before = getHostSibling(finishedWork);
17424
- // We only have the top Fiber that was inserted but we need recurse down its
17867
+ // We only have the top Fiber that was inserted but we need to recurse down its
17425
17868
  // children to find all the terminal nodes.
17426
17869
  var node = finishedWork;
17427
17870
  while (true) {
@@ -17463,7 +17906,7 @@ function commitPlacement(finishedWork) {
17463
17906
  }
17464
17907
 
17465
17908
  function unmountHostComponents(current$$1) {
17466
- // We only have the top Fiber that was deleted but we need recurse down its
17909
+ // We only have the top Fiber that was deleted but we need to recurse down its
17467
17910
  var node = current$$1;
17468
17911
 
17469
17912
  // Each iteration, currentParent is populated with node's host parent if not
@@ -17508,13 +17951,20 @@ function unmountHostComponents(current$$1) {
17508
17951
  removeChild(currentParent, node.stateNode);
17509
17952
  }
17510
17953
  // Don't visit children because we already visited them.
17954
+ } else if (enableSuspenseServerRenderer && node.tag === DehydratedSuspenseComponent) {
17955
+ // Delete the dehydrated suspense boundary and all of its content.
17956
+ if (currentParentIsContainer) {
17957
+ clearSuspenseBoundaryFromContainer(currentParent, node.stateNode);
17958
+ } else {
17959
+ clearSuspenseBoundary(currentParent, node.stateNode);
17960
+ }
17511
17961
  } else if (node.tag === HostPortal) {
17512
- // When we go into a portal, it becomes the parent to remove from.
17513
- // We will reassign it back when we pop the portal on the way up.
17514
- currentParent = node.stateNode.containerInfo;
17515
- currentParentIsContainer = true;
17516
- // Visit children because portals might contain host components.
17517
17962
  if (node.child !== null) {
17963
+ // When we go into a portal, it becomes the parent to remove from.
17964
+ // We will reassign it back when we pop the portal on the way up.
17965
+ currentParent = node.stateNode.containerInfo;
17966
+ currentParentIsContainer = true;
17967
+ // Visit children because portals might contain host components.
17518
17968
  node.child.return = node;
17519
17969
  node = node.child;
17520
17970
  continue;
@@ -17664,7 +18114,7 @@ function commitWork(current$$1, finishedWork) {
17664
18114
  finishedWork.updateQueue = null;
17665
18115
  var retryCache = finishedWork.stateNode;
17666
18116
  if (retryCache === null) {
17667
- retryCache = finishedWork.stateNode = new PossiblyWeakSet();
18117
+ retryCache = finishedWork.stateNode = new PossiblyWeakSet$1();
17668
18118
  }
17669
18119
  thenables.forEach(function (thenable) {
17670
18120
  // Memoize using the boundary fiber to prevent redundant listeners.
@@ -17699,6 +18149,7 @@ function commitResetTextContent(current$$1) {
17699
18149
  resetTextContent(current$$1.stateNode);
17700
18150
  }
17701
18151
 
18152
+ var PossiblyWeakSet = typeof WeakSet === 'function' ? WeakSet : Set;
17702
18153
  var PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map;
17703
18154
 
17704
18155
  function createRootErrorUpdate(fiber, errorInfo, expirationTime) {
@@ -17757,6 +18208,34 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) {
17757
18208
  return update;
17758
18209
  }
17759
18210
 
18211
+ function attachPingListener(root, renderExpirationTime, thenable) {
18212
+ // Attach a listener to the promise to "ping" the root and retry. But
18213
+ // only if one does not already exist for the current render expiration
18214
+ // time (which acts like a "thread ID" here).
18215
+ var pingCache = root.pingCache;
18216
+ var threadIDs = void 0;
18217
+ if (pingCache === null) {
18218
+ pingCache = root.pingCache = new PossiblyWeakMap();
18219
+ threadIDs = new Set();
18220
+ pingCache.set(thenable, threadIDs);
18221
+ } else {
18222
+ threadIDs = pingCache.get(thenable);
18223
+ if (threadIDs === undefined) {
18224
+ threadIDs = new Set();
18225
+ pingCache.set(thenable, threadIDs);
18226
+ }
18227
+ }
18228
+ if (!threadIDs.has(renderExpirationTime)) {
18229
+ // Memoize using the thread ID to prevent redundant listeners.
18230
+ threadIDs.add(renderExpirationTime);
18231
+ var ping = pingSuspendedRoot.bind(null, root, thenable, renderExpirationTime);
18232
+ if (enableSchedulerTracing) {
18233
+ ping = unstable_wrap(ping);
18234
+ }
18235
+ thenable.then(ping, ping);
18236
+ }
18237
+ }
18238
+
17760
18239
  function throwException(root, returnFiber, sourceFiber, value, renderExpirationTime) {
17761
18240
  // The source fiber did not complete.
17762
18241
  sourceFiber.effectTag |= Incomplete;
@@ -17798,6 +18277,9 @@ function throwException(root, returnFiber, sourceFiber, value, renderExpirationT
17798
18277
  }
17799
18278
  }
17800
18279
  }
18280
+ // If there is a DehydratedSuspenseComponent we don't have to do anything because
18281
+ // if something suspends inside it, we will simply leave that as dehydrated. It
18282
+ // will never timeout.
17801
18283
  _workInProgress = _workInProgress.return;
17802
18284
  } while (_workInProgress !== null);
17803
18285
 
@@ -17861,31 +18343,7 @@ function throwException(root, returnFiber, sourceFiber, value, renderExpirationT
17861
18343
  // Confirmed that the boundary is in a concurrent mode tree. Continue
17862
18344
  // with the normal suspend path.
17863
18345
 
17864
- // Attach a listener to the promise to "ping" the root and retry. But
17865
- // only if one does not already exist for the current render expiration
17866
- // time (which acts like a "thread ID" here).
17867
- var pingCache = root.pingCache;
17868
- var threadIDs = void 0;
17869
- if (pingCache === null) {
17870
- pingCache = root.pingCache = new PossiblyWeakMap();
17871
- threadIDs = new Set();
17872
- pingCache.set(thenable, threadIDs);
17873
- } else {
17874
- threadIDs = pingCache.get(thenable);
17875
- if (threadIDs === undefined) {
17876
- threadIDs = new Set();
17877
- pingCache.set(thenable, threadIDs);
17878
- }
17879
- }
17880
- if (!threadIDs.has(renderExpirationTime)) {
17881
- // Memoize using the thread ID to prevent redundant listeners.
17882
- threadIDs.add(renderExpirationTime);
17883
- var ping = pingSuspendedRoot.bind(null, root, thenable, renderExpirationTime);
17884
- if (enableSchedulerTracing) {
17885
- ping = unstable_wrap(ping);
17886
- }
17887
- thenable.then(ping, ping);
17888
- }
18346
+ attachPingListener(root, renderExpirationTime, thenable);
17889
18347
 
17890
18348
  var absoluteTimeoutMs = void 0;
17891
18349
  if (earliestTimeoutMs === -1) {
@@ -17917,6 +18375,29 @@ function throwException(root, returnFiber, sourceFiber, value, renderExpirationT
17917
18375
  // whole tree.
17918
18376
  renderDidSuspend(root, absoluteTimeoutMs, renderExpirationTime);
17919
18377
 
18378
+ _workInProgress.effectTag |= ShouldCapture;
18379
+ _workInProgress.expirationTime = renderExpirationTime;
18380
+ return;
18381
+ } else if (enableSuspenseServerRenderer && _workInProgress.tag === DehydratedSuspenseComponent) {
18382
+ attachPingListener(root, renderExpirationTime, thenable);
18383
+
18384
+ // Since we already have a current fiber, we can eagerly add a retry listener.
18385
+ var retryCache = _workInProgress.memoizedState;
18386
+ if (retryCache === null) {
18387
+ retryCache = _workInProgress.memoizedState = new PossiblyWeakSet();
18388
+ var _current = _workInProgress.alternate;
18389
+ !_current ? invariant(false, 'A dehydrated suspense boundary must commit before trying to render. This is probably a bug in React.') : void 0;
18390
+ _current.memoizedState = retryCache;
18391
+ }
18392
+ // Memoize using the boundary fiber to prevent redundant listeners.
18393
+ if (!retryCache.has(thenable)) {
18394
+ retryCache.add(thenable);
18395
+ var retry = retryTimedOutBoundary.bind(null, _workInProgress, thenable);
18396
+ if (enableSchedulerTracing) {
18397
+ retry = unstable_wrap(retry);
18398
+ }
18399
+ thenable.then(retry, retry);
18400
+ }
17920
18401
  _workInProgress.effectTag |= ShouldCapture;
17921
18402
  _workInProgress.expirationTime = renderExpirationTime;
17922
18403
  return;
@@ -17994,6 +18475,7 @@ function unwindWork(workInProgress, renderExpirationTime) {
17994
18475
  }
17995
18476
  case HostComponent:
17996
18477
  {
18478
+ // TODO: popHydrationState
17997
18479
  popHostContext(workInProgress);
17998
18480
  return null;
17999
18481
  }
@@ -18007,6 +18489,19 @@ function unwindWork(workInProgress, renderExpirationTime) {
18007
18489
  }
18008
18490
  return null;
18009
18491
  }
18492
+ case DehydratedSuspenseComponent:
18493
+ {
18494
+ if (enableSuspenseServerRenderer) {
18495
+ // TODO: popHydrationState
18496
+ var _effectTag3 = workInProgress.effectTag;
18497
+ if (_effectTag3 & ShouldCapture) {
18498
+ workInProgress.effectTag = _effectTag3 & ~ShouldCapture | DidCapture;
18499
+ // Captured a suspense effect. Re-render the boundary.
18500
+ return workInProgress;
18501
+ }
18502
+ }
18503
+ return null;
18504
+ }
18010
18505
  case HostPortal:
18011
18506
  popHostContainer(workInProgress);
18012
18507
  return null;
@@ -18104,11 +18599,6 @@ if (enableSchedulerTracing) {
18104
18599
  // Used to ensure computeUniqueAsyncExpiration is monotonically decreasing.
18105
18600
  var lastUniqueAsyncExpiration = Sync - 1;
18106
18601
 
18107
- // Represents the expiration time that incoming updates should use. (If this
18108
- // is NoWork, use the default strategy: async updates in async mode, sync
18109
- // updates in sync mode.)
18110
- var expirationContext = NoWork;
18111
-
18112
18602
  var isWorking = false;
18113
18603
 
18114
18604
  // The next work in progress fiber that we're currently working on.
@@ -18404,6 +18894,10 @@ function commitPassiveEffects(root, firstEffect) {
18404
18894
  if (rootExpirationTime !== NoWork) {
18405
18895
  requestWork(root, rootExpirationTime);
18406
18896
  }
18897
+ // Flush any sync work that was scheduled by effects
18898
+ if (!isBatchingUpdates && !isRendering) {
18899
+ performSyncWork();
18900
+ }
18407
18901
  }
18408
18902
 
18409
18903
  function isAlreadyFailedLegacyErrorBoundary(instance) {
@@ -18578,7 +19072,9 @@ function commitRoot(root, finishedWork) {
18578
19072
  // here because that code is still in flux.
18579
19073
  callback = unstable_wrap(callback);
18580
19074
  }
18581
- passiveEffectCallbackHandle = schedulePassiveEffects(callback);
19075
+ passiveEffectCallbackHandle = unstable_runWithPriority(unstable_NormalPriority, function () {
19076
+ return schedulePassiveEffects(callback);
19077
+ });
18582
19078
  passiveEffectCallback = callback;
18583
19079
  }
18584
19080
 
@@ -19167,7 +19663,7 @@ function renderRoot(root, isYieldy) {
19167
19663
  return;
19168
19664
  } else if (
19169
19665
  // There's no lower priority work, but we're rendering asynchronously.
19170
- // Synchronsouly attempt to render the same level one more time. This is
19666
+ // Synchronously attempt to render the same level one more time. This is
19171
19667
  // similar to a suspend, but without a timeout because we're not waiting
19172
19668
  // for a promise to resolve.
19173
19669
  !root.didError && isYieldy) {
@@ -19272,49 +19768,50 @@ function computeUniqueAsyncExpiration() {
19272
19768
  }
19273
19769
 
19274
19770
  function computeExpirationForFiber(currentTime, fiber) {
19771
+ var priorityLevel = unstable_getCurrentPriorityLevel();
19772
+
19275
19773
  var expirationTime = void 0;
19276
- if (expirationContext !== NoWork) {
19277
- // An explicit expiration context was set;
19278
- expirationTime = expirationContext;
19279
- } else if (isWorking) {
19280
- if (isCommitting$1) {
19281
- // Updates that occur during the commit phase should have sync priority
19282
- // by default.
19283
- expirationTime = Sync;
19284
- } else {
19285
- // Updates during the render phase should expire at the same time as
19286
- // the work that is being rendered.
19287
- expirationTime = nextRenderExpirationTime;
19288
- }
19774
+ if ((fiber.mode & ConcurrentMode) === NoContext) {
19775
+ // Outside of concurrent mode, updates are always synchronous.
19776
+ expirationTime = Sync;
19777
+ } else if (isWorking && !isCommitting$1) {
19778
+ // During render phase, updates expire during as the current render.
19779
+ expirationTime = nextRenderExpirationTime;
19289
19780
  } else {
19290
- // No explicit expiration context was set, and we're not currently
19291
- // performing work. Calculate a new expiration time.
19292
- if (fiber.mode & ConcurrentMode) {
19293
- if (isBatchingInteractiveUpdates) {
19294
- // This is an interactive update
19781
+ switch (priorityLevel) {
19782
+ case unstable_ImmediatePriority:
19783
+ expirationTime = Sync;
19784
+ break;
19785
+ case unstable_UserBlockingPriority:
19295
19786
  expirationTime = computeInteractiveExpiration(currentTime);
19296
- } else {
19297
- // This is an async update
19787
+ break;
19788
+ case unstable_NormalPriority:
19789
+ // This is a normal, concurrent update
19298
19790
  expirationTime = computeAsyncExpiration(currentTime);
19299
- }
19300
- // If we're in the middle of rendering a tree, do not update at the same
19301
- // expiration time that is already rendering.
19302
- if (nextRoot !== null && expirationTime === nextRenderExpirationTime) {
19303
- expirationTime -= 1;
19304
- }
19305
- } else {
19306
- // This is a sync update
19307
- expirationTime = Sync;
19791
+ break;
19792
+ case unstable_LowPriority:
19793
+ case unstable_IdlePriority:
19794
+ expirationTime = Never;
19795
+ break;
19796
+ default:
19797
+ invariant(false, 'Unknown priority level. This error is likely caused by a bug in React. Please file an issue.');
19308
19798
  }
19309
- }
19310
- if (isBatchingInteractiveUpdates) {
19311
- // This is an interactive update. Keep track of the lowest pending
19312
- // interactive expiration time. This allows us to synchronously flush
19313
- // all interactive updates when needed.
19314
- if (lowestPriorityPendingInteractiveExpirationTime === NoWork || expirationTime < lowestPriorityPendingInteractiveExpirationTime) {
19315
- lowestPriorityPendingInteractiveExpirationTime = expirationTime;
19799
+
19800
+ // If we're in the middle of rendering a tree, do not update at the same
19801
+ // expiration time that is already rendering.
19802
+ if (nextRoot !== null && expirationTime === nextRenderExpirationTime) {
19803
+ expirationTime -= 1;
19316
19804
  }
19317
19805
  }
19806
+
19807
+ // Keep track of the lowest pending interactive expiration time. This
19808
+ // allows us to synchronously flush all interactive updates
19809
+ // when needed.
19810
+ // TODO: Move this to renderer?
19811
+ if (priorityLevel === unstable_UserBlockingPriority && (lowestPriorityPendingInteractiveExpirationTime === NoWork || expirationTime < lowestPriorityPendingInteractiveExpirationTime)) {
19812
+ lowestPriorityPendingInteractiveExpirationTime = expirationTime;
19813
+ }
19814
+
19318
19815
  return expirationTime;
19319
19816
  }
19320
19817
 
@@ -19361,7 +19858,21 @@ function retryTimedOutBoundary(boundaryFiber, thenable) {
19361
19858
  // The boundary fiber (a Suspense component) previously timed out and was
19362
19859
  // rendered in its fallback state. One of the promises that suspended it has
19363
19860
  // resolved, which means at least part of the tree was likely unblocked. Try
19364
- var retryCache = boundaryFiber.stateNode;
19861
+ var retryCache = void 0;
19862
+ if (enableSuspenseServerRenderer) {
19863
+ switch (boundaryFiber.tag) {
19864
+ case SuspenseComponent:
19865
+ retryCache = boundaryFiber.stateNode;
19866
+ break;
19867
+ case DehydratedSuspenseComponent:
19868
+ retryCache = boundaryFiber.memoizedState;
19869
+ break;
19870
+ default:
19871
+ invariant(false, 'Pinged unknown suspense boundary type. This is probably a bug in React.');
19872
+ }
19873
+ } else {
19874
+ retryCache = boundaryFiber.stateNode;
19875
+ }
19365
19876
  if (retryCache !== null) {
19366
19877
  // The thenable resolved, so we no longer need to memoize, because it will
19367
19878
  // never be thrown again.
@@ -19460,7 +19971,7 @@ function scheduleWorkToRoot(fiber, expirationTime) {
19460
19971
  function warnIfNotCurrentlyBatchingInDev(fiber) {
19461
19972
  {
19462
19973
  if (isRendering === false && isBatchingUpdates === false) {
19463
- 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));
19974
+ 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));
19464
19975
  }
19465
19976
  }
19466
19977
  }
@@ -19507,13 +20018,9 @@ function scheduleWork(fiber, expirationTime) {
19507
20018
  }
19508
20019
 
19509
20020
  function syncUpdates(fn, a, b, c, d) {
19510
- var previousExpirationContext = expirationContext;
19511
- expirationContext = Sync;
19512
- try {
20021
+ return unstable_runWithPriority(unstable_ImmediatePriority, function () {
19513
20022
  return fn(a, b, c, d);
19514
- } finally {
19515
- expirationContext = previousExpirationContext;
19516
- }
20023
+ });
19517
20024
  }
19518
20025
 
19519
20026
  // TODO: Everything below this is written as if it has been lifted to the
@@ -19534,7 +20041,6 @@ var unhandledError = null;
19534
20041
 
19535
20042
  var isBatchingUpdates = false;
19536
20043
  var isUnbatchingUpdates = false;
19537
- var isBatchingInteractiveUpdates = false;
19538
20044
 
19539
20045
  var completedBatches = null;
19540
20046
 
@@ -20008,7 +20514,9 @@ function completeRoot(root, finishedWork, expirationTime) {
20008
20514
  lastCommittedRootDuringThisBatch = root;
20009
20515
  nestedUpdateCount = 0;
20010
20516
  }
20011
- commitRoot(root, finishedWork);
20517
+ unstable_runWithPriority(unstable_ImmediatePriority, function () {
20518
+ commitRoot(root, finishedWork);
20519
+ });
20012
20520
  }
20013
20521
 
20014
20522
  function onUncaughtError(error) {
@@ -20066,9 +20574,6 @@ function flushSync(fn, a) {
20066
20574
  }
20067
20575
 
20068
20576
  function interactiveUpdates$1(fn, a, b) {
20069
- if (isBatchingInteractiveUpdates) {
20070
- return fn(a, b);
20071
- }
20072
20577
  // If there are any pending interactive updates, synchronously flush them.
20073
20578
  // This needs to happen before we read any handlers, because the effect of
20074
20579
  // the previous event may influence which handlers are called during
@@ -20078,14 +20583,13 @@ function interactiveUpdates$1(fn, a, b) {
20078
20583
  performWork(lowestPriorityPendingInteractiveExpirationTime, false);
20079
20584
  lowestPriorityPendingInteractiveExpirationTime = NoWork;
20080
20585
  }
20081
- var previousIsBatchingInteractiveUpdates = isBatchingInteractiveUpdates;
20082
20586
  var previousIsBatchingUpdates = isBatchingUpdates;
20083
- isBatchingInteractiveUpdates = true;
20084
20587
  isBatchingUpdates = true;
20085
20588
  try {
20086
- return fn(a, b);
20589
+ return unstable_runWithPriority(unstable_UserBlockingPriority, function () {
20590
+ return fn(a, b);
20591
+ });
20087
20592
  } finally {
20088
- isBatchingInteractiveUpdates = previousIsBatchingInteractiveUpdates;
20089
20593
  isBatchingUpdates = previousIsBatchingUpdates;
20090
20594
  if (!isBatchingUpdates && !isRendering) {
20091
20595
  performSyncWork();
@@ -20348,7 +20852,7 @@ implementation) {
20348
20852
 
20349
20853
  // TODO: this is special because it gets imported during build.
20350
20854
 
20351
- var ReactVersion = '16.8.1';
20855
+ var ReactVersion = '16.8.5';
20352
20856
 
20353
20857
  // TODO: This type is shared between the reconciler and ReactDOM, but will
20354
20858
  // eventually be lifted out to the renderer.
@@ -20738,7 +21242,7 @@ var ReactDOM = {
20738
21242
  hydrate: function (element, container, callback) {
20739
21243
  !isValidContainer(container) ? invariant(false, 'Target container is not a DOM element.') : void 0;
20740
21244
  {
20741
- !!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;
21245
+ !!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;
20742
21246
  }
20743
21247
  // TODO: throw or warn if we couldn't hydrate?
20744
21248
  return legacyRenderSubtreeIntoContainer(null, element, container, true, callback);