diff --git a/Libraries/Renderer/REVISION b/Libraries/Renderer/REVISION index 1899fb63526..ba0ce2996c4 100644 --- a/Libraries/Renderer/REVISION +++ b/Libraries/Renderer/REVISION @@ -1 +1 @@ -25dda90c1ecb0c662ab06e2c80c1ee31e0ae9d36 \ No newline at end of file +0887c7d56cb9b83f36dcb490b4245d7bc33bda1f \ No newline at end of file diff --git a/Libraries/Renderer/oss/ReactFabric-dev.js b/Libraries/Renderer/oss/ReactFabric-dev.js index 3b52fb146ce..0424315c8ed 100644 --- a/Libraries/Renderer/oss/ReactFabric-dev.js +++ b/Libraries/Renderer/oss/ReactFabric-dev.js @@ -5,7 +5,6 @@ * LICENSE file in the root directory of this source tree. * * @noflow - * @providesModule ReactFabric-dev * @preventMunge */ @@ -26,8 +25,8 @@ var deepDiffer = require("deepDiffer"); var flattenStyle = require("flattenStyle"); var React = require("react"); var emptyObject = require("fbjs/lib/emptyObject"); -var checkPropTypes = require("prop-types/checkPropTypes"); var shallowEqual = require("fbjs/lib/shallowEqual"); +var checkPropTypes = require("prop-types/checkPropTypes"); var deepFreezeAndThrowOnMutationInDev = require("deepFreezeAndThrowOnMutationInDev"); var FabricUIManager = require("FabricUIManager"); @@ -816,7 +815,7 @@ var ForwardRef = 14; function getParent(inst) { do { - inst = inst.return; + inst = inst["return"]; // TODO: If this is a HostRoot we might want to bail out. // That is depending on if we want nested subtrees (layers) to bubble // events to their parent. We could also go through parentNode on the @@ -2313,21 +2312,23 @@ injection.injectEventPluginsByName({ // The Symbol used to tag the ReactElement-like types. If there is no native Symbol // nor polyfill, then a plain number is used for performance. -var hasSymbol = typeof Symbol === "function" && Symbol.for; +var hasSymbol = typeof Symbol === "function" && Symbol["for"]; -var REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for("react.element") : 0xeac7; -var REACT_CALL_TYPE = hasSymbol ? Symbol.for("react.call") : 0xeac8; -var REACT_RETURN_TYPE = hasSymbol ? Symbol.for("react.return") : 0xeac9; -var REACT_PORTAL_TYPE = hasSymbol ? Symbol.for("react.portal") : 0xeaca; -var REACT_FRAGMENT_TYPE = hasSymbol ? Symbol.for("react.fragment") : 0xeacb; +var REACT_ELEMENT_TYPE = hasSymbol ? Symbol["for"]("react.element") : 0xeac7; +var REACT_CALL_TYPE = hasSymbol ? Symbol["for"]("react.call") : 0xeac8; +var REACT_RETURN_TYPE = hasSymbol ? Symbol["for"]("react.return") : 0xeac9; +var REACT_PORTAL_TYPE = hasSymbol ? Symbol["for"]("react.portal") : 0xeaca; +var REACT_FRAGMENT_TYPE = hasSymbol ? Symbol["for"]("react.fragment") : 0xeacb; var REACT_STRICT_MODE_TYPE = hasSymbol - ? Symbol.for("react.strict_mode") + ? Symbol["for"]("react.strict_mode") : 0xeacc; -var REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for("react.provider") : 0xeacd; -var REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for("react.context") : 0xeace; -var REACT_ASYNC_MODE_TYPE = hasSymbol ? Symbol.for("react.async_mode") : 0xeacf; +var REACT_PROVIDER_TYPE = hasSymbol ? Symbol["for"]("react.provider") : 0xeacd; +var REACT_CONTEXT_TYPE = hasSymbol ? Symbol["for"]("react.context") : 0xeace; +var REACT_ASYNC_MODE_TYPE = hasSymbol + ? Symbol["for"]("react.async_mode") + : 0xeacf; var REACT_FORWARD_REF_TYPE = hasSymbol - ? Symbol.for("react.forward_ref") + ? Symbol["for"]("react.forward_ref") : 0xead0; var MAYBE_ITERATOR_SYMBOL = typeof Symbol === "function" && Symbol.iterator; @@ -3410,10 +3411,11 @@ var ContentReset = /* */ 16; var Callback = /* */ 32; var DidCapture = /* */ 64; var Ref = /* */ 128; -var Snapshot = /* */ 256; +var ErrLog = /* */ 256; +var Snapshot = /* */ 2048; // Union of all host effects -var HostEffectMask = /* */ 511; +var HostEffectMask = /* */ 2559; var Incomplete = /* */ 512; var ShouldCapture = /* */ 1024; @@ -3430,15 +3432,15 @@ function isFiberMountedImpl(fiber) { if ((node.effectTag & Placement) !== NoEffect) { return MOUNTING; } - while (node.return) { - node = node.return; + while (node["return"]) { + node = node["return"]; if ((node.effectTag & Placement) !== NoEffect) { return MOUNTING; } } } else { - while (node.return) { - node = node.return; + while (node["return"]) { + node = node["return"]; } } if (node.tag === HostRoot) { @@ -3510,7 +3512,7 @@ function findCurrentFiberUsingSlowPath(fiber) { var a = fiber; var b = alternate; while (true) { - var parentA = a.return; + var parentA = a["return"]; var parentB = parentA ? parentA.alternate : null; if (!parentA || !parentB) { // We're at the root. @@ -3540,7 +3542,7 @@ function findCurrentFiberUsingSlowPath(fiber) { invariant(false, "Unable to find node on an unmounted component."); } - if (a.return !== b.return) { + if (a["return"] !== b["return"]) { // The return pointer of A and the return pointer of B point to different // fibers. We assume that return pointers never criss-cross, so A must // belong to the child set of A.return, and B must belong to the child @@ -3628,7 +3630,7 @@ function findCurrentHostFiber(parent) { if (node.tag === HostComponent || node.tag === HostText) { return node; } else if (node.child) { - node.child.return = node; + node.child["return"] = node; node = node.child; continue; } @@ -3636,12 +3638,12 @@ function findCurrentHostFiber(parent) { return null; } while (!node.sibling) { - if (!node.return || node.return === currentParent) { + if (!node["return"] || node["return"] === currentParent) { return null; } - node = node.return; + node = node["return"]; } - node.sibling.return = node.return; + node.sibling["return"] = node["return"]; node = node.sibling; } // Flow needs the return null here, but ESLint complains about it. @@ -3661,7 +3663,7 @@ function findCurrentHostFiberWithNoPortals(parent) { if (node.tag === HostComponent || node.tag === HostText) { return node; } else if (node.child && node.tag !== HostPortal) { - node.child.return = node; + node.child["return"] = node; node = node.child; continue; } @@ -3669,12 +3671,12 @@ function findCurrentHostFiberWithNoPortals(parent) { return null; } while (!node.sibling) { - if (!node.return || node.return === currentParent) { + if (!node["return"] || node["return"] === currentParent) { return null; } - node = node.return; + node = node["return"]; } - node.sibling.return = node.return; + node.sibling["return"] = node["return"]; node = node.sibling; } // Flow needs the return null here, but ESLint complains about it. @@ -3757,7 +3759,7 @@ function FiberNode(tag, pendingProps, key, mode) { this.stateNode = null; // Fiber - this.return = null; + this["return"] = null; this.child = null; this.sibling = null; this.index = 0; @@ -4042,7 +4044,7 @@ function assignFiberPropertiesInDEV(target, source) { target.key = source.key; target.type = source.type; target.stateNode = source.stateNode; - target.return = source.return; + target["return"] = source["return"]; target.child = source.child; target.sibling = source.sibling; target.index = source.index; @@ -4202,7 +4204,7 @@ function getStackAddendumByWorkInProgressFiber(workInProgress) { do { info += describeFiber(node); // Otherwise this return pointer might point to the wrong tree: - node = node.return; + node = node["return"]; } while (node); return info; } @@ -4372,7 +4374,7 @@ var ReactStrictModeWarnings = { maybeStrictRoot = fiber; } - fiber = fiber.return; + fiber = fiber["return"]; } return maybeStrictRoot; @@ -4493,6 +4495,16 @@ var ReactStrictModeWarnings = { return; } + // Don't warn about react-lifecycles-compat polyfilled components. + // Note that it is sufficient to check for the presence of a + // single lifecycle, componentWillMount, with the polyfill flag. + if ( + typeof instance.componentWillMount === "function" && + instance.componentWillMount.__suppressDeprecationWarning === true + ) { + return; + } + var warningsForRoot = void 0; if (!pendingUnsafeLifecycleWarnings.has(strictRoot)) { warningsForRoot = { @@ -4508,23 +4520,19 @@ var ReactStrictModeWarnings = { var unsafeLifecycles = []; if ( - (typeof instance.componentWillMount === "function" && - instance.componentWillMount.__suppressDeprecationWarning !== true) || + typeof instance.componentWillMount === "function" || typeof instance.UNSAFE_componentWillMount === "function" ) { unsafeLifecycles.push("UNSAFE_componentWillMount"); } if ( - (typeof instance.componentWillReceiveProps === "function" && - instance.componentWillReceiveProps.__suppressDeprecationWarning !== - true) || + typeof instance.componentWillReceiveProps === "function" || typeof instance.UNSAFE_componentWillReceiveProps === "function" ) { unsafeLifecycles.push("UNSAFE_componentWillReceiveProps"); } if ( - (typeof instance.componentWillUpdate === "function" && - instance.componentWillUpdate.__suppressDeprecationWarning !== true) || + typeof instance.componentWillUpdate === "function" || typeof instance.UNSAFE_componentWillUpdate === "function" ) { unsafeLifecycles.push("UNSAFE_componentWillUpdate"); @@ -4566,7 +4574,7 @@ function getCurrentFiberOwnerName() { return null; } -function getCurrentFiberStackAddendum$1() { +function getCurrentFiberStackAddendum() { { var fiber = ReactDebugCurrentFiber.current; if (fiber === null) { @@ -4586,7 +4594,7 @@ function resetCurrentFiber() { } function setCurrentFiber(fiber) { - ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackAddendum$1; + ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackAddendum; ReactDebugCurrentFiber.current = fiber; ReactDebugCurrentFiber.phase = null; } @@ -4602,7 +4610,7 @@ var ReactDebugCurrentFiber = { setCurrentFiber: setCurrentFiber, setCurrentPhase: setCurrentPhase, getCurrentFiberOwnerName: getCurrentFiberOwnerName, - getCurrentFiberStackAddendum: getCurrentFiberStackAddendum$1 + getCurrentFiberStackAddendum: getCurrentFiberStackAddendum }; // Prefix measurements so that it's possible to filter them. @@ -4759,13 +4767,13 @@ var pauseTimers = function() { if (fiber._debugIsCurrentlyTiming) { endFiberMark(fiber, null, null); } - fiber = fiber.return; + fiber = fiber["return"]; } }; var resumeTimersRecursively = function(fiber) { - if (fiber.return !== null) { - resumeTimersRecursively(fiber.return); + if (fiber["return"] !== null) { + resumeTimersRecursively(fiber["return"]); } if (fiber._debugIsCurrentlyTiming) { beginFiberMark(fiber, null); @@ -4857,7 +4865,7 @@ function stopWorkTimer(fiber) { return; } // If we pause, its parent is the fiber to unwind from. - currentFiber = fiber.return; + currentFiber = fiber["return"]; if (!fiber._debugIsCurrentlyTiming) { return; } @@ -4872,7 +4880,7 @@ function stopFailedWorkTimer(fiber) { return; } // If we pause, its parent is the fiber to unwind from. - currentFiber = fiber.return; + currentFiber = fiber["return"]; if (!fiber._debugIsCurrentlyTiming) { return; } @@ -5062,232 +5070,100 @@ function stopCommitLifeCyclesTimer() { } } -// UpdateQueue is a linked list of prioritized updates. -// -// Like fibers, update queues come in pairs: a current queue, which represents -// the visible state of the screen, and a work-in-progress queue, which is -// can be mutated and processed asynchronously before it is committed — a form -// of double buffering. If a work-in-progress render is discarded before -// finishing, we create a new work-in-progress by cloning the current queue. -// -// Both queues share a persistent, singly-linked list structure. To schedule an -// update, we append it to the end of both queues. Each queue maintains a -// pointer to first update in the persistent list that hasn't been processed. -// The work-in-progress pointer always has a position equal to or greater than -// the current queue, since we always work on that one. The current queue's -// pointer is only updated during the commit phase, when we swap in the -// work-in-progress. -// -// For example: -// -// Current pointer: A - B - C - D - E - F -// Work-in-progress pointer: D - E - F -// ^ -// The work-in-progress queue has -// processed more updates than current. -// -// The reason we append to both queues is because otherwise we might drop -// updates without ever processing them. For example, if we only add updates to -// the work-in-progress queue, some updates could be lost whenever a work-in -// -progress render restarts by cloning from current. Similarly, if we only add -// updates to the current queue, the updates will be lost whenever an already -// in-progress queue commits and swaps with the current queue. However, by -// adding to both queues, we guarantee that the update will be part of the next -// work-in-progress. (And because the work-in-progress queue becomes the -// current queue once it commits, there's no danger of applying the same -// update twice.) -// -// Prioritization -// -------------- -// -// Updates are not sorted by priority, but by insertion; new updates are always -// appended to the end of the list. -// -// The priority is still important, though. When processing the update queue -// during the render phase, only the updates with sufficient priority are -// included in the result. If we skip an update because it has insufficient -// priority, it remains in the queue to be processed later, during a lower -// priority render. Crucially, all updates subsequent to a skipped update also -// remain in the queue *regardless of their priority*. That means high priority -// updates are sometimes processed twice, at two separate priorities. We also -// keep track of a base state, that represents the state before the first -// update in the queue is applied. -// -// For example: -// -// Given a base state of '', and the following queue of updates -// -// A1 - B2 - C1 - D2 -// -// where the number indicates the priority, and the update is applied to the -// previous state by appending a letter, React will process these updates as -// two separate renders, one per distinct priority level: -// -// First render, at priority 1: -// Base state: '' -// Updates: [A1, C1] -// Result state: 'AC' -// -// Second render, at priority 2: -// Base state: 'A' <- The base state does not include C1, -// because B2 was skipped. -// Updates: [B2, C1, D2] <- C1 was rebased on top of B2 -// Result state: 'ABCD' -// -// Because we process updates in insertion order, and rebase high priority -// updates when preceding updates are skipped, the final result is deterministic -// regardless of priority. Intermediate state may vary according to system -// resources, but the final state is always the same. - -var UpdateState = 0; -var ReplaceState = 1; -var ForceUpdate = 2; -var CaptureUpdate = 3; - var didWarnUpdateInsideUpdate = void 0; -var currentlyProcessingQueue = void 0; -var resetCurrentlyProcessingQueue = void 0; + { didWarnUpdateInsideUpdate = false; - currentlyProcessingQueue = null; - resetCurrentlyProcessingQueue = function() { - currentlyProcessingQueue = null; - }; } +// Callbacks are not validated until invocation + +// Singly linked-list of updates. When an update is scheduled, it is added to +// the queue of the current fiber and the work-in-progress fiber. The two queues +// are separate but they share a persistent structure. +// +// During reconciliation, updates are removed from the work-in-progress fiber, +// but they remain on the current fiber. That ensures that if a work-in-progress +// is aborted, the aborted updates are recovered by cloning from current. +// +// The work-in-progress queue is always a subset of the current queue. +// +// When the tree is committed, the work-in-progress becomes the current. + function createUpdateQueue(baseState) { var queue = { - expirationTime: NoWork, baseState: baseState, - firstUpdate: null, - lastUpdate: null, - firstCapturedUpdate: null, - lastCapturedUpdate: null, - firstEffect: null, - lastEffect: null, - firstCapturedEffect: null, - lastCapturedEffect: null, - hasForceUpdate: false - }; - return queue; -} - -function cloneUpdateQueue(currentQueue) { - var queue = { - expirationTime: currentQueue.expirationTime, - baseState: currentQueue.baseState, - firstUpdate: currentQueue.firstUpdate, - lastUpdate: currentQueue.lastUpdate, - - // TODO: With resuming, if we bail out and resuse the child tree, we should - // keep these effects. - firstCapturedUpdate: null, - lastCapturedUpdate: null, - + expirationTime: NoWork, + first: null, + last: null, + callbackList: null, hasForceUpdate: false, - - firstEffect: null, - lastEffect: null, - - firstCapturedEffect: null, - lastCapturedEffect: null + isInitialized: false, + capturedValues: null }; + { + queue.isProcessing = false; + } return queue; } -function createUpdate(expirationTime) { - return { - expirationTime: expirationTime, - - tag: UpdateState, - payload: null, - callback: null, - - next: null, - nextEffect: null - }; -} - -function appendUpdateToQueue(queue, update, expirationTime) { +function insertUpdateIntoQueue(queue, update) { // Append the update to the end of the list. - if (queue.lastUpdate === null) { + if (queue.last === null) { // Queue is empty - queue.firstUpdate = queue.lastUpdate = update; + queue.first = queue.last = update; } else { - queue.lastUpdate.next = update; - queue.lastUpdate = update; + queue.last.next = update; + queue.last = update; } if ( queue.expirationTime === NoWork || - queue.expirationTime > expirationTime + queue.expirationTime > update.expirationTime ) { - // The incoming update has the earliest expiration of any update in the - // queue. Update the queue's expiration time. - queue.expirationTime = expirationTime; + queue.expirationTime = update.expirationTime; } } -function enqueueUpdate(fiber, update, expirationTime) { - // Update queues are created lazily. - var alternate = fiber.alternate; - var queue1 = void 0; - var queue2 = void 0; - if (alternate === null) { - // There's only one fiber. - queue1 = fiber.updateQueue; - queue2 = null; - if (queue1 === null) { - queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState); - } - } else { - // There are two owners. - queue1 = fiber.updateQueue; - queue2 = alternate.updateQueue; - if (queue1 === null) { - if (queue2 === null) { - // Neither fiber has an update queue. Create new ones. - queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState); - queue2 = alternate.updateQueue = createUpdateQueue( - alternate.memoizedState - ); - } else { - // Only one fiber has an update queue. Clone to create a new one. - queue1 = fiber.updateQueue = cloneUpdateQueue(queue2); - } - } else { - if (queue2 === null) { - // Only one fiber has an update queue. Clone to create a new one. - queue2 = alternate.updateQueue = cloneUpdateQueue(queue1); - } else { - // Both owners have an update queue. - } - } - } - if (queue2 === null || queue1 === queue2) { - // There's only a single queue. - appendUpdateToQueue(queue1, update, expirationTime); - } else { - // There are two queues. We need to append the update to both queues, - // while accounting for the persistent structure of the list — we don't - // want the same update to be added multiple times. - if (queue1.lastUpdate === null || queue2.lastUpdate === null) { - // One of the queues is not empty. We must add the update to both queues. - appendUpdateToQueue(queue1, update, expirationTime); - appendUpdateToQueue(queue2, update, expirationTime); - } else { - // Both queues are non-empty. The last update is the same in both lists, - // because of structural sharing. So, only append to one of the lists. - appendUpdateToQueue(queue1, update, expirationTime); - // But we still need to update the `lastUpdate` pointer of queue2. - queue2.lastUpdate = update; - } +var q1 = void 0; +var q2 = void 0; +function ensureUpdateQueues(fiber) { + q1 = q2 = null; + // We'll have at least one and at most two distinct update queues. + var alternateFiber = fiber.alternate; + var queue1 = fiber.updateQueue; + if (queue1 === null) { + // TODO: We don't know what the base state will be until we begin work. + // It depends on which fiber is the next current. Initialize with an empty + // base state, then set to the memoizedState when rendering. Not super + // happy with this approach. + queue1 = fiber.updateQueue = createUpdateQueue(null); } + var queue2 = void 0; + if (alternateFiber !== null) { + queue2 = alternateFiber.updateQueue; + if (queue2 === null) { + queue2 = alternateFiber.updateQueue = createUpdateQueue(null); + } + } else { + queue2 = null; + } + queue2 = queue2 !== queue1 ? queue2 : null; + + // Use module variables instead of returning a tuple + q1 = queue1; + q2 = queue2; +} + +function insertUpdateIntoFiber(fiber, update) { + ensureUpdateQueues(fiber); + var queue1 = q1; + var queue2 = q2; + + // Warn if an update is scheduled from inside an updater function. { if ( - fiber.tag === ClassComponent && - (currentlyProcessingQueue === queue1 || - (queue2 !== null && currentlyProcessingQueue === queue2)) && + (queue1.isProcessing || (queue2 !== null && queue2.isProcessing)) && !didWarnUpdateInsideUpdate ) { warning( @@ -5300,328 +5176,225 @@ function enqueueUpdate(fiber, update, expirationTime) { didWarnUpdateInsideUpdate = true; } } -} -function enqueueCapturedUpdate(workInProgress, update, renderExpirationTime) { - // Captured updates go into a separate list, and only on the work-in- - // progress queue. - var workInProgressQueue = workInProgress.updateQueue; - if (workInProgressQueue === null) { - workInProgressQueue = workInProgress.updateQueue = createUpdateQueue( - workInProgress.memoizedState - ); - } else { - // TODO: I put this here rather than createWorkInProgress so that we don't - // clone the queue unnecessarily. There's probably a better way to - // structure this. - workInProgressQueue = ensureWorkInProgressQueueIsAClone( - workInProgress, - workInProgressQueue - ); - } - - // Append the update to the end of the list. - if (workInProgressQueue.lastCapturedUpdate === null) { - // This is the first render phase update - workInProgressQueue.firstCapturedUpdate = workInProgressQueue.lastCapturedUpdate = update; - } else { - workInProgressQueue.lastCapturedUpdate.next = update; - workInProgressQueue.lastCapturedUpdate = update; - } - if ( - workInProgressQueue.expirationTime === NoWork || - workInProgressQueue.expirationTime > renderExpirationTime - ) { - // The incoming update has the earliest expiration of any update in the - // queue. Update the queue's expiration time. - workInProgressQueue.expirationTime = renderExpirationTime; - } -} - -function ensureWorkInProgressQueueIsAClone(workInProgress, queue) { - var current = workInProgress.alternate; - if (current !== null) { - // If the work-in-progress queue is equal to the current queue, - // we need to clone it first. - if (queue === current.updateQueue) { - queue = workInProgress.updateQueue = cloneUpdateQueue(queue); - } - } - return queue; -} - -function getStateFromUpdate( - workInProgress, - queue, - update, - prevState, - nextProps, - instance -) { - switch (update.tag) { - case ReplaceState: { - var _payload = update.payload; - if (typeof _payload === "function") { - // Updater function - { - if ( - debugRenderPhaseSideEffects || - (debugRenderPhaseSideEffectsForStrictMode && - workInProgress.mode & StrictMode) - ) { - _payload.call(instance, prevState, nextProps); - } - } - return _payload.call(instance, prevState, nextProps); - } - // State object - return _payload; - } - case CaptureUpdate: { - workInProgress.effectTag = - (workInProgress.effectTag & ~ShouldCapture) | DidCapture; - } - // Intentional fallthrough - case UpdateState: { - var _payload2 = update.payload; - var partialState = void 0; - if (typeof _payload2 === "function") { - // Updater function - { - if ( - debugRenderPhaseSideEffects || - (debugRenderPhaseSideEffectsForStrictMode && - workInProgress.mode & StrictMode) - ) { - _payload2.call(instance, prevState, nextProps); - } - } - partialState = _payload2.call(instance, prevState, nextProps); - } else { - // Partial state object - partialState = _payload2; - } - if (partialState === null || partialState === undefined) { - // Null and undefined are treated as no-ops. - return prevState; - } - // Merge the partial state and the previous state. - return Object.assign({}, prevState, partialState); - } - case ForceUpdate: { - queue.hasForceUpdate = true; - return prevState; - } - } - return prevState; -} - -function processUpdateQueue( - workInProgress, - queue, - props, - instance, - renderExpirationTime -) { - if ( - queue.expirationTime === NoWork || - queue.expirationTime > renderExpirationTime - ) { - // Insufficient priority. Bailout. + // If there's only one queue, add the update to that queue and exit. + if (queue2 === null) { + insertUpdateIntoQueue(queue1, update); return; } - queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue); - - { - currentlyProcessingQueue = queue; + // If either queue is empty, we need to add to both queues. + if (queue1.last === null || queue2.last === null) { + insertUpdateIntoQueue(queue1, update); + insertUpdateIntoQueue(queue2, update); + return; } - // These values may change as we process the queue. - var newBaseState = queue.baseState; - var newFirstUpdate = null; - var newExpirationTime = NoWork; + // If both lists are not empty, the last update is the same for both lists + // because of structural sharing. So, we should only append to one of + // the lists. + insertUpdateIntoQueue(queue1, update); + // But we still need to update the `last` pointer of queue2. + queue2.last = update; +} - // Iterate through the list of updates to compute the result. - var update = queue.firstUpdate; - var resultState = newBaseState; +function getUpdateExpirationTime(fiber) { + switch (fiber.tag) { + case HostRoot: + case ClassComponent: + var updateQueue = fiber.updateQueue; + if (updateQueue === null) { + return NoWork; + } + return updateQueue.expirationTime; + default: + return NoWork; + } +} + +function getStateFromUpdate(update, instance, prevState, props) { + var partialState = update.partialState; + if (typeof partialState === "function") { + return partialState.call(instance, prevState, props); + } else { + return partialState; + } +} + +function processUpdateQueue( + current, + workInProgress, + queue, + instance, + props, + renderExpirationTime +) { + if (current !== null && current.updateQueue === queue) { + // We need to create a work-in-progress queue, by cloning the current queue. + var currentQueue = queue; + queue = workInProgress.updateQueue = { + baseState: currentQueue.baseState, + expirationTime: currentQueue.expirationTime, + first: currentQueue.first, + last: currentQueue.last, + isInitialized: currentQueue.isInitialized, + capturedValues: currentQueue.capturedValues, + // These fields are no longer valid because they were already committed. + // Reset them. + callbackList: null, + hasForceUpdate: false + }; + } + + { + // Set this flag so we can warn if setState is called inside the update + // function of another setState. + queue.isProcessing = true; + } + + // Reset the remaining expiration time. If we skip over any updates, we'll + // increase this accordingly. + queue.expirationTime = NoWork; + + // TODO: We don't know what the base state will be until we begin work. + // It depends on which fiber is the next current. Initialize with an empty + // base state, then set to the memoizedState when rendering. Not super + // happy with this approach. + var state = void 0; + if (queue.isInitialized) { + state = queue.baseState; + } else { + state = queue.baseState = workInProgress.memoizedState; + queue.isInitialized = true; + } + var dontMutatePrevState = true; + var update = queue.first; + var didSkip = false; while (update !== null) { var updateExpirationTime = update.expirationTime; if (updateExpirationTime > renderExpirationTime) { // This update does not have sufficient priority. Skip it. - if (newFirstUpdate === null) { - // This is the first skipped update. It will be the first update in - // the new list. - newFirstUpdate = update; - // Since this is the first update that was skipped, the current result - // is the new base state. - newBaseState = resultState; - } - // Since this update will remain in the list, update the remaining - // expiration time. + var remainingExpirationTime = queue.expirationTime; if ( - newExpirationTime === NoWork || - newExpirationTime > updateExpirationTime + remainingExpirationTime === NoWork || + remainingExpirationTime > updateExpirationTime ) { - newExpirationTime = updateExpirationTime; + // Update the remaining expiration time. + queue.expirationTime = updateExpirationTime; } - } else { - // This update does have sufficient priority. Process it and compute - // a new result. - resultState = getStateFromUpdate( - workInProgress, - queue, - update, - resultState, - props, - instance - ); - var _callback = update.callback; - if (_callback !== null) { - workInProgress.effectTag |= Callback; - // Set this to null, in case it was mutated during an aborted render. - update.nextEffect = null; - if (queue.lastEffect === null) { - queue.firstEffect = queue.lastEffect = update; - } else { - queue.lastEffect.nextEffect = update; - queue.lastEffect = update; - } + if (!didSkip) { + didSkip = true; + queue.baseState = state; + } + // Continue to the next update. + update = update.next; + continue; + } + + // This update does have sufficient priority. + + // If no previous updates were skipped, drop this update from the queue by + // advancing the head of the list. + if (!didSkip) { + queue.first = update.next; + if (queue.first === null) { + queue.last = null; } } - // Continue to the next update. - update = update.next; - } - // Separately, iterate though the list of captured updates. - var newFirstCapturedUpdate = null; - update = queue.firstCapturedUpdate; - while (update !== null) { - var _updateExpirationTime = update.expirationTime; - if (_updateExpirationTime > renderExpirationTime) { - // This update does not have sufficient priority. Skip it. - if (newFirstCapturedUpdate === null) { - // This is the first skipped captured update. It will be the first - // update in the new list. - newFirstCapturedUpdate = update; - // If this is the first update that was skipped, the current result is - // the new base state. - if (newFirstUpdate === null) { - newBaseState = resultState; - } - } - // Since this update will remain in the list, update the remaining - // expiration time. - if ( - newExpirationTime === NoWork || - newExpirationTime > _updateExpirationTime - ) { - newExpirationTime = _updateExpirationTime; - } + // Invoke setState callback an extra time to help detect side-effects. + // Ignore the return value in this case. + if ( + debugRenderPhaseSideEffects || + (debugRenderPhaseSideEffectsForStrictMode && + workInProgress.mode & StrictMode) + ) { + getStateFromUpdate(update, instance, state, props); + } + + // Process the update + var _partialState = void 0; + if (update.isReplace) { + state = getStateFromUpdate(update, instance, state, props); + dontMutatePrevState = true; } else { - // This update does have sufficient priority. Process it and compute - // a new result. - resultState = getStateFromUpdate( - workInProgress, - queue, - update, - resultState, - props, - instance - ); - var _callback2 = update.callback; - if (_callback2 !== null) { - workInProgress.effectTag |= Callback; - // Set this to null, in case it was mutated during an aborted render. - update.nextEffect = null; - if (queue.lastCapturedEffect === null) { - queue.firstCapturedEffect = queue.lastCapturedEffect = update; + _partialState = getStateFromUpdate(update, instance, state, props); + if (_partialState) { + if (dontMutatePrevState) { + // $FlowFixMe: Idk how to type this properly. + state = Object.assign({}, state, _partialState); } else { - queue.lastCapturedEffect.nextEffect = update; - queue.lastCapturedEffect = update; + state = Object.assign(state, _partialState); } + dontMutatePrevState = false; + } + } + if (update.isForced) { + queue.hasForceUpdate = true; + } + if (update.callback !== null) { + // Append to list of callbacks. + var _callbackList = queue.callbackList; + if (_callbackList === null) { + _callbackList = queue.callbackList = []; + } + _callbackList.push(update); + } + if (update.capturedValue !== null) { + var _capturedValues = queue.capturedValues; + if (_capturedValues === null) { + queue.capturedValues = [update.capturedValue]; + } else { + _capturedValues.push(update.capturedValue); } } update = update.next; } - if (newFirstUpdate === null) { - queue.lastUpdate = null; - } - if (newFirstCapturedUpdate === null) { - queue.lastCapturedUpdate = null; - } else { + if (queue.callbackList !== null) { workInProgress.effectTag |= Callback; - } - if (newFirstUpdate === null && newFirstCapturedUpdate === null) { - // We processed every update, without skipping. That means the new base - // state is the same as the result state. - newBaseState = resultState; + } else if ( + queue.first === null && + !queue.hasForceUpdate && + queue.capturedValues === null + ) { + // The queue is empty. We can reset it. + workInProgress.updateQueue = null; } - queue.baseState = newBaseState; - queue.firstUpdate = newFirstUpdate; - queue.firstCapturedUpdate = newFirstCapturedUpdate; - queue.expirationTime = newExpirationTime; - - workInProgress.memoizedState = resultState; + if (!didSkip) { + didSkip = true; + queue.baseState = state; + } { - currentlyProcessingQueue = null; + // No longer processing. + queue.isProcessing = false; } + + return state; } -function callCallback(callback, context) { - invariant( - typeof callback === "function", - "Invalid argument passed as callback. Expected a function. Instead " + - "received: %s", - callback - ); - callback.call(context); -} - -function commitUpdateQueue( - finishedWork, - finishedQueue, - instance, - renderExpirationTime -) { - // If the finished render included captured updates, and there are still - // lower priority updates left over, we need to keep the captured updates - // in the queue so that they are rebased and not dropped once we process the - // queue again at the lower priority. - if (finishedQueue.firstCapturedUpdate !== null) { - // Join the captured update list to the end of the normal list. - if (finishedQueue.lastUpdate !== null) { - finishedQueue.lastUpdate.next = finishedQueue.firstCapturedUpdate; - finishedQueue.lastUpdate = finishedQueue.lastCapturedUpdate; - } - // Clear the list of captured updates. - finishedQueue.firstCapturedUpdate = finishedQueue.lastCapturedUpdate = null; +function commitCallbacks(queue, context) { + var callbackList = queue.callbackList; + if (callbackList === null) { + return; } - - // Commit the effects - var effect = finishedQueue.firstEffect; - finishedQueue.firstEffect = finishedQueue.lastEffect = null; - while (effect !== null) { - var _callback3 = effect.callback; - if (_callback3 !== null) { - effect.callback = null; - callCallback(_callback3, instance); - } - effect = effect.nextEffect; - } - - effect = finishedQueue.firstCapturedEffect; - finishedQueue.firstCapturedEffect = finishedQueue.lastCapturedEffect = null; - while (effect !== null) { - var _callback4 = effect.callback; - if (_callback4 !== null) { - effect.callback = null; - callCallback(_callback4, instance); - } - effect = effect.nextEffect; + // Set the list to null to make sure they don't get called more than once. + queue.callbackList = null; + for (var i = 0; i < callbackList.length; i++) { + var update = callbackList[i]; + var _callback = update.callback; + // This update might be processed again. Clear the callback so it's only + // called once. + update.callback = null; + invariant( + typeof _callback === "function", + "Invalid argument passed as callback. Expected a function. Instead " + + "received: %s", + _callback + ); + _callback.call(context); } } @@ -5629,19 +5402,18 @@ var fakeInternalInstance = {}; var isArray = Array.isArray; var didWarnAboutStateAssignmentForComponent = void 0; +var didWarnAboutUndefinedDerivedState = void 0; var didWarnAboutUninitializedState = void 0; var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = void 0; var didWarnAboutLegacyLifecyclesAndDerivedState = void 0; -var didWarnAboutUndefinedDerivedState = void 0; -var warnOnUndefinedDerivedState = void 0; var warnOnInvalidCallback = void 0; { didWarnAboutStateAssignmentForComponent = new Set(); + didWarnAboutUndefinedDerivedState = new Set(); didWarnAboutUninitializedState = new Set(); didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set(); didWarnAboutLegacyLifecyclesAndDerivedState = new Set(); - didWarnAboutUndefinedDerivedState = new Set(); var didWarnOnInvalidCallback = new Set(); @@ -5662,21 +5434,6 @@ var warnOnInvalidCallback = void 0; } }; - warnOnUndefinedDerivedState = function(workInProgress, partialState) { - if (partialState === undefined) { - var componentName = getComponentName(workInProgress) || "Component"; - if (!didWarnAboutUndefinedDerivedState.has(componentName)) { - didWarnAboutUndefinedDerivedState.add(componentName); - warning( - false, - "%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. " + - "You have returned undefined.", - componentName - ); - } - } - }; - // This is so gross but it's at least non-critical and can be removed if // it causes problems. This is meant to give a nicer error message for // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component, @@ -5698,43 +5455,17 @@ var warnOnInvalidCallback = void 0; }); Object.freeze(fakeInternalInstance); } - -function applyDerivedStateFromProps( - workInProgress, - getDerivedStateFromProps, - nextProps -) { - var prevState = workInProgress.memoizedState; - - { - if ( - debugRenderPhaseSideEffects || - (debugRenderPhaseSideEffectsForStrictMode && - workInProgress.mode & StrictMode) - ) { - // Invoke the function an extra time to help detect side-effects. - getDerivedStateFromProps(nextProps, prevState); +function callGetDerivedStateFromCatch(ctor, capturedValues) { + var resultState = {}; + for (var i = 0; i < capturedValues.length; i++) { + var capturedValue = capturedValues[i]; + var error = capturedValue.value; + var partialState = ctor.getDerivedStateFromCatch.call(null, error); + if (partialState !== null && partialState !== undefined) { + Object.assign(resultState, partialState); } } - - var partialState = getDerivedStateFromProps(nextProps, prevState); - - { - warnOnUndefinedDerivedState(workInProgress, partialState); - } - // Merge the partial state and the previous state. - var memoizedState = - partialState === null || partialState === undefined - ? prevState - : Object.assign({}, prevState, partialState); - workInProgress.memoizedState = memoizedState; - - // Once the update queue is empty, persist the derived state onto the - // base state. - var updateQueue = workInProgress.updateQueue; - if (updateQueue !== null && updateQueue.expirationTime === NoWork) { - updateQueue.baseState = memoizedState; - } + return resultState; } var ReactFiberClassComponent = function( @@ -5750,57 +5481,65 @@ var ReactFiberClassComponent = function( isContextConsumer = legacyContext.isContextConsumer, hasContextChanged = legacyContext.hasContextChanged; - var classComponentUpdater = { + // Class component state updater + + var updater = { isMounted: isMounted, - enqueueSetState: function(inst, payload, callback) { - var fiber = get$1(inst); - var expirationTime = computeExpirationForFiber(fiber); - - var update = createUpdate(expirationTime); - update.payload = payload; - if (callback !== undefined && callback !== null) { - { - warnOnInvalidCallback(callback, "setState"); - } - update.callback = callback; + enqueueSetState: function(instance, partialState, callback) { + var fiber = get$1(instance); + callback = callback === undefined ? null : callback; + { + warnOnInvalidCallback(callback, "setState"); } - - enqueueUpdate(fiber, update, expirationTime); + var expirationTime = computeExpirationForFiber(fiber); + var update = { + expirationTime: expirationTime, + partialState: partialState, + callback: callback, + isReplace: false, + isForced: false, + capturedValue: null, + next: null + }; + insertUpdateIntoFiber(fiber, update); scheduleWork(fiber, expirationTime); }, - enqueueReplaceState: function(inst, payload, callback) { - var fiber = get$1(inst); - var expirationTime = computeExpirationForFiber(fiber); - - var update = createUpdate(expirationTime); - update.tag = ReplaceState; - update.payload = payload; - - if (callback !== undefined && callback !== null) { - { - warnOnInvalidCallback(callback, "replaceState"); - } - update.callback = callback; + enqueueReplaceState: function(instance, state, callback) { + var fiber = get$1(instance); + callback = callback === undefined ? null : callback; + { + warnOnInvalidCallback(callback, "replaceState"); } - - enqueueUpdate(fiber, update, expirationTime); + var expirationTime = computeExpirationForFiber(fiber); + var update = { + expirationTime: expirationTime, + partialState: state, + callback: callback, + isReplace: true, + isForced: false, + capturedValue: null, + next: null + }; + insertUpdateIntoFiber(fiber, update); scheduleWork(fiber, expirationTime); }, - enqueueForceUpdate: function(inst, callback) { - var fiber = get$1(inst); - var expirationTime = computeExpirationForFiber(fiber); - - var update = createUpdate(expirationTime); - update.tag = ForceUpdate; - - if (callback !== undefined && callback !== null) { - { - warnOnInvalidCallback(callback, "forceUpdate"); - } - update.callback = callback; + enqueueForceUpdate: function(instance, callback) { + var fiber = get$1(instance); + callback = callback === undefined ? null : callback; + { + warnOnInvalidCallback(callback, "forceUpdate"); } - - enqueueUpdate(fiber, update, expirationTime); + var expirationTime = computeExpirationForFiber(fiber); + var update = { + expirationTime: expirationTime, + partialState: null, + callback: callback, + isReplace: false, + isForced: true, + capturedValue: null, + next: null + }; + insertUpdateIntoFiber(fiber, update); scheduleWork(fiber, expirationTime); } }; @@ -5814,10 +5553,11 @@ var ReactFiberClassComponent = function( newContext ) { if ( - workInProgress.updateQueue !== null && - workInProgress.updateQueue.hasForceUpdate + oldProps === null || + (workInProgress.updateQueue !== null && + workInProgress.updateQueue.hasForceUpdate) ) { - // If forceUpdate was called, disregard sCU. + // If the workInProgress already has an Update effect, return true return true; } @@ -6074,8 +5814,13 @@ var ReactFiberClassComponent = function( } } + function resetInputPointers(workInProgress, instance) { + instance.props = workInProgress.memoizedProps; + instance.state = workInProgress.memoizedState; + } + function adoptClassInstance(workInProgress, instance) { - instance.updater = classComponentUpdater; + instance.updater = updater; workInProgress.stateNode = instance; // The instance needs access to the fiber so that it can schedule updates set(instance, workInProgress); @@ -6084,7 +5829,7 @@ var ReactFiberClassComponent = function( } } - function constructClassInstance(workInProgress, props, renderExpirationTime) { + function constructClassInstance(workInProgress, props) { var ctor = workInProgress.type; var unmaskedContext = getUnmaskedContext(workInProgress); var needsContext = isContextConsumer(workInProgress); @@ -6093,21 +5838,19 @@ var ReactFiberClassComponent = function( : emptyObject; // Instantiate twice to help detect side-effects. - { - if ( - debugRenderPhaseSideEffects || - (debugRenderPhaseSideEffectsForStrictMode && - workInProgress.mode & StrictMode) - ) { - new ctor(props, context); // eslint-disable-line no-new - } + if ( + debugRenderPhaseSideEffects || + (debugRenderPhaseSideEffectsForStrictMode && + workInProgress.mode & StrictMode) + ) { + new ctor(props, context); // eslint-disable-line no-new } var instance = new ctor(props, context); - var state = (workInProgress.memoizedState = + var state = instance.state !== null && instance.state !== undefined ? instance.state - : null); + : null; adoptClassInstance(workInProgress, instance); { @@ -6198,6 +5941,26 @@ var ReactFiberClassComponent = function( } } + workInProgress.memoizedState = state; + + var partialState = callGetDerivedStateFromProps( + workInProgress, + instance, + props, + state + ); + + if (partialState !== null && partialState !== undefined) { + // Render-phase updates (like this) should not be added to the update queue, + // So that multiple render passes do not enqueue multiple updates. + // Instead, just synchronously merge the returned state into the instance. + workInProgress.memoizedState = Object.assign( + {}, + workInProgress.memoizedState, + partialState + ); + } + // Cache unmasked context so we can avoid recreating masked context unless necessary. // ReactFiberContext usually updates this cache but can't for newly-created instances. if (needsContext) { @@ -6230,7 +5993,7 @@ var ReactFiberClassComponent = function( getComponentName(workInProgress) || "Component" ); } - classComponentUpdater.enqueueReplaceState(instance, instance.state, null); + updater.enqueueReplaceState(instance, instance.state, null); } } @@ -6264,13 +6027,57 @@ var ReactFiberClassComponent = function( ); } } - classComponentUpdater.enqueueReplaceState(instance, instance.state, null); + updater.enqueueReplaceState(instance, instance.state, null); + } + } + + function callGetDerivedStateFromProps( + workInProgress, + instance, + nextProps, + prevState + ) { + var type = workInProgress.type; + + if (typeof type.getDerivedStateFromProps === "function") { + if ( + debugRenderPhaseSideEffects || + (debugRenderPhaseSideEffectsForStrictMode && + workInProgress.mode & StrictMode) + ) { + // Invoke method an extra time to help detect side-effects. + type.getDerivedStateFromProps.call(null, nextProps, prevState); + } + + var partialState = type.getDerivedStateFromProps.call( + null, + nextProps, + prevState + ); + + { + if (partialState === undefined) { + var componentName = getComponentName(workInProgress) || "Component"; + if (!didWarnAboutUndefinedDerivedState.has(componentName)) { + didWarnAboutUndefinedDerivedState.add(componentName); + warning( + false, + "%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. " + + "You have returned undefined.", + componentName + ); + } + } + } + + return partialState; } } // Invokes the mount life-cycles on a previously never rendered instance. function mountClassInstance(workInProgress, renderExpirationTime) { var ctor = workInProgress.type; + var current = workInProgress.alternate; { checkClassInstance(workInProgress); @@ -6301,28 +6108,6 @@ var ReactFiberClassComponent = function( } } - var updateQueue = workInProgress.updateQueue; - if (updateQueue !== null) { - processUpdateQueue( - workInProgress, - updateQueue, - props, - instance, - renderExpirationTime - ); - instance.state = workInProgress.memoizedState; - } - - var getDerivedStateFromProps = workInProgress.type.getDerivedStateFromProps; - if (typeof getDerivedStateFromProps === "function") { - applyDerivedStateFromProps( - workInProgress, - getDerivedStateFromProps, - props - ); - instance.state = workInProgress.memoizedState; - } - // In order to support react-lifecycles-compat polyfilled components, // Unsafe lifecycles should not be invoked for components using the new APIs. if ( @@ -6334,19 +6119,18 @@ var ReactFiberClassComponent = function( callComponentWillMount(workInProgress, instance); // If we had additional state updates during this life-cycle, let's // process them now. - updateQueue = workInProgress.updateQueue; + var updateQueue = workInProgress.updateQueue; if (updateQueue !== null) { - processUpdateQueue( + instance.state = processUpdateQueue( + current, workInProgress, updateQueue, - props, instance, + props, renderExpirationTime ); - instance.state = workInProgress.memoizedState; } } - if (typeof instance.componentDidMount === "function") { workInProgress.effectTag |= Update; } @@ -6355,18 +6139,16 @@ var ReactFiberClassComponent = function( function resumeMountClassInstance(workInProgress, renderExpirationTime) { var ctor = workInProgress.type; var instance = workInProgress.stateNode; + resetInputPointers(workInProgress, instance); var oldProps = workInProgress.memoizedProps; var newProps = workInProgress.pendingProps; - instance.props = oldProps; - var oldContext = instance.context; var newUnmaskedContext = getUnmaskedContext(workInProgress); var newContext = getMaskedContext(workInProgress, newUnmaskedContext); - var getDerivedStateFromProps = ctor.getDerivedStateFromProps; var hasNewLifecycles = - typeof getDerivedStateFromProps === "function" || + typeof ctor.getDerivedStateFromProps === "function" || typeof instance.getSnapshotBeforeUpdate === "function"; // Note: During these life-cycles, instance.props/instance.state are what @@ -6390,27 +6172,93 @@ var ReactFiberClassComponent = function( } } + // Compute the next state using the memoized state and the update queue. var oldState = workInProgress.memoizedState; - var newState = (instance.state = oldState); - var updateQueue = workInProgress.updateQueue; - if (updateQueue !== null) { - processUpdateQueue( + // TODO: Previous state can be null. + var newState = void 0; + var derivedStateFromCatch = void 0; + if (workInProgress.updateQueue !== null) { + newState = processUpdateQueue( + null, workInProgress, - updateQueue, - newProps, + workInProgress.updateQueue, instance, + newProps, renderExpirationTime ); - newState = workInProgress.memoizedState; + + var updateQueue = workInProgress.updateQueue; + if ( + updateQueue !== null && + updateQueue.capturedValues !== null && + enableGetDerivedStateFromCatch && + typeof ctor.getDerivedStateFromCatch === "function" + ) { + var capturedValues = updateQueue.capturedValues; + // Don't remove these from the update queue yet. We need them in + // finishClassComponent. Do the reset there. + // TODO: This is awkward. Refactor class components. + // updateQueue.capturedValues = null; + derivedStateFromCatch = callGetDerivedStateFromCatch( + ctor, + capturedValues + ); + } + } else { + newState = oldState; } - if (typeof getDerivedStateFromProps === "function") { - applyDerivedStateFromProps( + var derivedStateFromProps = void 0; + if (oldProps !== newProps) { + // The prevState parameter should be the partially updated state. + // Otherwise, spreading state in return values could override updates. + derivedStateFromProps = callGetDerivedStateFromProps( workInProgress, - getDerivedStateFromProps, - newProps + instance, + newProps, + newState ); - newState = workInProgress.memoizedState; + } + + if (derivedStateFromProps !== null && derivedStateFromProps !== undefined) { + // Render-phase updates (like this) should not be added to the update queue, + // So that multiple render passes do not enqueue multiple updates. + // Instead, just synchronously merge the returned state into the instance. + newState = + newState === null || newState === undefined + ? derivedStateFromProps + : Object.assign({}, newState, derivedStateFromProps); + + // Update the base state of the update queue. + // FIXME: This is getting ridiculous. Refactor plz! + var _updateQueue = workInProgress.updateQueue; + if (_updateQueue !== null) { + _updateQueue.baseState = Object.assign( + {}, + _updateQueue.baseState, + derivedStateFromProps + ); + } + } + if (derivedStateFromCatch !== null && derivedStateFromCatch !== undefined) { + // Render-phase updates (like this) should not be added to the update queue, + // So that multiple render passes do not enqueue multiple updates. + // Instead, just synchronously merge the returned state into the instance. + newState = + newState === null || newState === undefined + ? derivedStateFromCatch + : Object.assign({}, newState, derivedStateFromCatch); + + // Update the base state of the update queue. + // FIXME: This is getting ridiculous. Refactor plz! + var _updateQueue2 = workInProgress.updateQueue; + if (_updateQueue2 !== null) { + _updateQueue2.baseState = Object.assign( + {}, + _updateQueue2.baseState, + derivedStateFromCatch + ); + } } if ( @@ -6467,9 +6315,9 @@ var ReactFiberClassComponent = function( } // If shouldComponentUpdate returned false, we should still update the - // memoized state to indicate that this work can be reused. - workInProgress.memoizedProps = newProps; - workInProgress.memoizedState = newState; + // memoized props/state to indicate that this work can be reused. + memoizeProps(workInProgress, newProps); + memoizeState(workInProgress, newState); } // Update the existing instance's state, props, and context pointers even @@ -6485,18 +6333,16 @@ var ReactFiberClassComponent = function( function updateClassInstance(current, workInProgress, renderExpirationTime) { var ctor = workInProgress.type; var instance = workInProgress.stateNode; + resetInputPointers(workInProgress, instance); var oldProps = workInProgress.memoizedProps; var newProps = workInProgress.pendingProps; - instance.props = oldProps; - var oldContext = instance.context; var newUnmaskedContext = getUnmaskedContext(workInProgress); var newContext = getMaskedContext(workInProgress, newUnmaskedContext); - var getDerivedStateFromProps = ctor.getDerivedStateFromProps; var hasNewLifecycles = - typeof getDerivedStateFromProps === "function" || + typeof ctor.getDerivedStateFromProps === "function" || typeof instance.getSnapshotBeforeUpdate === "function"; // Note: During these life-cycles, instance.props/instance.state are what @@ -6520,27 +6366,94 @@ var ReactFiberClassComponent = function( } } + // Compute the next state using the memoized state and the update queue. var oldState = workInProgress.memoizedState; - var newState = (instance.state = oldState); - var updateQueue = workInProgress.updateQueue; - if (updateQueue !== null) { - processUpdateQueue( + // TODO: Previous state can be null. + var newState = void 0; + var derivedStateFromCatch = void 0; + + if (workInProgress.updateQueue !== null) { + newState = processUpdateQueue( + current, workInProgress, - updateQueue, - newProps, + workInProgress.updateQueue, instance, + newProps, renderExpirationTime ); - newState = workInProgress.memoizedState; + + var updateQueue = workInProgress.updateQueue; + if ( + updateQueue !== null && + updateQueue.capturedValues !== null && + enableGetDerivedStateFromCatch && + typeof ctor.getDerivedStateFromCatch === "function" + ) { + var capturedValues = updateQueue.capturedValues; + // Don't remove these from the update queue yet. We need them in + // finishClassComponent. Do the reset there. + // TODO: This is awkward. Refactor class components. + // updateQueue.capturedValues = null; + derivedStateFromCatch = callGetDerivedStateFromCatch( + ctor, + capturedValues + ); + } + } else { + newState = oldState; } - if (typeof getDerivedStateFromProps === "function") { - applyDerivedStateFromProps( + var derivedStateFromProps = void 0; + if (oldProps !== newProps) { + // The prevState parameter should be the partially updated state. + // Otherwise, spreading state in return values could override updates. + derivedStateFromProps = callGetDerivedStateFromProps( workInProgress, - getDerivedStateFromProps, - newProps + instance, + newProps, + newState ); - newState = workInProgress.memoizedState; + } + + if (derivedStateFromProps !== null && derivedStateFromProps !== undefined) { + // Render-phase updates (like this) should not be added to the update queue, + // So that multiple render passes do not enqueue multiple updates. + // Instead, just synchronously merge the returned state into the instance. + newState = + newState === null || newState === undefined + ? derivedStateFromProps + : Object.assign({}, newState, derivedStateFromProps); + + // Update the base state of the update queue. + // FIXME: This is getting ridiculous. Refactor plz! + var _updateQueue3 = workInProgress.updateQueue; + if (_updateQueue3 !== null) { + _updateQueue3.baseState = Object.assign( + {}, + _updateQueue3.baseState, + derivedStateFromProps + ); + } + } + if (derivedStateFromCatch !== null && derivedStateFromCatch !== undefined) { + // Render-phase updates (like this) should not be added to the update queue, + // So that multiple render passes do not enqueue multiple updates. + // Instead, just synchronously merge the returned state into the instance. + newState = + newState === null || newState === undefined + ? derivedStateFromCatch + : Object.assign({}, newState, derivedStateFromCatch); + + // Update the base state of the update queue. + // FIXME: This is getting ridiculous. Refactor plz! + var _updateQueue4 = workInProgress.updateQueue; + if (_updateQueue4 !== null) { + _updateQueue4.baseState = Object.assign( + {}, + _updateQueue4.baseState, + derivedStateFromCatch + ); + } } if ( @@ -6627,8 +6540,8 @@ var ReactFiberClassComponent = function( // If shouldComponentUpdate returned false, we should still update the // memoized props/state to indicate that this work can be reused. - workInProgress.memoizedProps = newProps; - workInProgress.memoizedState = newState; + memoizeProps(workInProgress, newProps); + memoizeState(workInProgress, newState); } // Update the existing instance's state, props, and context pointers even @@ -6642,6 +6555,7 @@ var ReactFiberClassComponent = function( return { adoptClassInstance: adoptClassInstance, + callGetDerivedStateFromProps: callGetDerivedStateFromProps, constructClassInstance: constructClassInstance, mountClassInstance: mountClassInstance, resumeMountClassInstance: resumeMountClassInstance, @@ -6649,7 +6563,7 @@ var ReactFiberClassComponent = function( }; }; -var getCurrentFiberStackAddendum$2 = +var getCurrentFiberStackAddendum$1 = ReactDebugCurrentFiber.getCurrentFiberStackAddendum; var didWarnAboutMaps = void 0; @@ -6688,7 +6602,7 @@ var warnForMissingKey = function(child) {}; "Each child in an array or iterator should have a unique " + '"key" prop. See https://fb.me/react-warning-keys for ' + "more information." + - (getCurrentFiberStackAddendum$2() || ""); + (getCurrentFiberStackAddendum$1() || ""); if (ownerHasKeyUseWarning[currentComponentErrorInfo]) { return; } @@ -6699,7 +6613,7 @@ var warnForMissingKey = function(child) {}; "Each child in an array or iterator should have a unique " + '"key" prop. See https://fb.me/react-warning-keys for ' + "more information.%s", - getCurrentFiberStackAddendum$2() + getCurrentFiberStackAddendum$1() ); }; } @@ -6796,7 +6710,7 @@ function throwOnInvalidObjectType(returnFiber, newChild) { addendum = " If you meant to render a collection of children, use an array " + "instead." + - (getCurrentFiberStackAddendum$2() || ""); + (getCurrentFiberStackAddendum$1() || ""); } invariant( false, @@ -6814,7 +6728,7 @@ function warnOnFunctionType() { "Functions are not valid as a React child. This may happen if " + "you return a Component instead of from render. " + "Or maybe you meant to call this function rather than return it." + - (getCurrentFiberStackAddendum$2() || ""); + (getCurrentFiberStackAddendum$1() || ""); if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) { return; @@ -6826,7 +6740,7 @@ function warnOnFunctionType() { "Functions are not valid as a React child. This may happen if " + "you return a Component instead of from render. " + "Or maybe you meant to call this function rather than return it.%s", - getCurrentFiberStackAddendum$2() || "" + getCurrentFiberStackAddendum$1() || "" ); } @@ -6939,12 +6853,12 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime ); - created.return = returnFiber; + created["return"] = returnFiber; return created; } else { // Update var existing = useFiber(current, textContent, expirationTime); - existing.return = returnFiber; + existing["return"] = returnFiber; return existing; } } @@ -6954,7 +6868,7 @@ function ChildReconciler(shouldTrackSideEffects) { // Move based on index var existing = useFiber(current, element.props, expirationTime); existing.ref = coerceRef(returnFiber, current, element); - existing.return = returnFiber; + existing["return"] = returnFiber; { existing._debugSource = element._source; existing._debugOwner = element._owner; @@ -6968,7 +6882,7 @@ function ChildReconciler(shouldTrackSideEffects) { expirationTime ); created.ref = coerceRef(returnFiber, current, element); - created.return = returnFiber; + created["return"] = returnFiber; return created; } } @@ -6986,12 +6900,12 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime ); - created.return = returnFiber; + created["return"] = returnFiber; return created; } else { // Update var existing = useFiber(current, portal.children || [], expirationTime); - existing.return = returnFiber; + existing["return"] = returnFiber; return existing; } } @@ -7005,12 +6919,12 @@ function ChildReconciler(shouldTrackSideEffects) { expirationTime, key ); - created.return = returnFiber; + created["return"] = returnFiber; return created; } else { // Update var existing = useFiber(current, fragment, expirationTime); - existing.return = returnFiber; + existing["return"] = returnFiber; return existing; } } @@ -7025,7 +6939,7 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime ); - created.return = returnFiber; + created["return"] = returnFiber; return created; } @@ -7038,7 +6952,7 @@ function ChildReconciler(shouldTrackSideEffects) { expirationTime ); _created.ref = coerceRef(returnFiber, null, newChild); - _created.return = returnFiber; + _created["return"] = returnFiber; return _created; } case REACT_PORTAL_TYPE: { @@ -7047,7 +6961,7 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime ); - _created2.return = returnFiber; + _created2["return"] = returnFiber; return _created2; } } @@ -7059,7 +6973,7 @@ function ChildReconciler(shouldTrackSideEffects) { expirationTime, null ); - _created3.return = returnFiber; + _created3["return"] = returnFiber; return _created3; } @@ -7270,7 +7184,7 @@ function ChildReconciler(shouldTrackSideEffects) { "duplicated and/or omitted — the behavior is unsupported and " + "could change in a future version.%s", key, - getCurrentFiberStackAddendum$2() + getCurrentFiberStackAddendum$1() ); break; default: @@ -7415,7 +7329,7 @@ function ChildReconciler(shouldTrackSideEffects) { // current, that means that we reused the fiber. We need to delete // it from the child list so that we don't add it to the deletion // list. - existingChildren.delete( + existingChildren["delete"]( _newFiber2.key === null ? newIdx : _newFiber2.key ); } @@ -7468,7 +7382,7 @@ function ChildReconciler(shouldTrackSideEffects) { "Using Maps as children is unsupported and will likely yield " + "unexpected results. Convert it to a sequence/iterable of keyed " + "ReactElements instead.%s", - getCurrentFiberStackAddendum$2() + getCurrentFiberStackAddendum$1() ) : void 0; didWarnAboutMaps = true; @@ -7594,7 +7508,7 @@ function ChildReconciler(shouldTrackSideEffects) { // current, that means that we reused the fiber. We need to delete // it from the child list so that we don't add it to the deletion // list. - existingChildren.delete( + existingChildren["delete"]( _newFiber4.key === null ? newIdx : _newFiber4.key ); } @@ -7633,7 +7547,7 @@ function ChildReconciler(shouldTrackSideEffects) { // the rest. deleteRemainingChildren(returnFiber, currentFirstChild.sibling); var existing = useFiber(currentFirstChild, textContent, expirationTime); - existing.return = returnFiber; + existing["return"] = returnFiber; return existing; } // The existing first child is not a text node so we need to create one @@ -7644,7 +7558,7 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime ); - created.return = returnFiber; + created["return"] = returnFiber; return created; } @@ -7674,7 +7588,7 @@ function ChildReconciler(shouldTrackSideEffects) { expirationTime ); existing.ref = coerceRef(returnFiber, child, element); - existing.return = returnFiber; + existing["return"] = returnFiber; { existing._debugSource = element._source; existing._debugOwner = element._owner; @@ -7697,7 +7611,7 @@ function ChildReconciler(shouldTrackSideEffects) { expirationTime, element.key ); - created.return = returnFiber; + created["return"] = returnFiber; return created; } else { var _created4 = createFiberFromElement( @@ -7706,7 +7620,7 @@ function ChildReconciler(shouldTrackSideEffects) { expirationTime ); _created4.ref = coerceRef(returnFiber, currentFirstChild, element); - _created4.return = returnFiber; + _created4["return"] = returnFiber; return _created4; } } @@ -7730,7 +7644,7 @@ function ChildReconciler(shouldTrackSideEffects) { ) { deleteRemainingChildren(returnFiber, child.sibling); var existing = useFiber(child, portal.children || [], expirationTime); - existing.return = returnFiber; + existing["return"] = returnFiber; return existing; } else { deleteRemainingChildren(returnFiber, child); @@ -7747,7 +7661,7 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime ); - created.return = returnFiber; + created["return"] = returnFiber; return created; } @@ -7899,7 +7813,7 @@ function cloneChildFibers(current, workInProgress) { ); workInProgress.child = newChild; - newChild.return = workInProgress; + newChild["return"] = workInProgress; while (currentChild.sibling !== null) { currentChild = currentChild.sibling; newChild = newChild.sibling = createWorkInProgress( @@ -7907,14 +7821,11 @@ function cloneChildFibers(current, workInProgress) { currentChild.pendingProps, currentChild.expirationTime ); - newChild.return = workInProgress; + newChild["return"] = workInProgress; } newChild.sibling = null; } -var getCurrentFiberStackAddendum = - ReactDebugCurrentFiber.getCurrentFiberStackAddendum; - var didWarnAboutBadClass = void 0; var didWarnAboutGetDerivedStateOnFunctionalComponent = void 0; var didWarnAboutStatelessRefs = void 0; @@ -7958,6 +7869,8 @@ var ReactFiberBeginWork = function( memoizeState ), adoptClassInstance = _ReactFiberClassCompo.adoptClassInstance, + callGetDerivedStateFromProps = + _ReactFiberClassCompo.callGetDerivedStateFromProps, constructClassInstance = _ReactFiberClassCompo.constructClassInstance, mountClassInstance = _ReactFiberClassCompo.mountClassInstance, resumeMountClassInstance = _ReactFiberClassCompo.resumeMountClassInstance, @@ -8009,20 +7922,9 @@ var ReactFiberBeginWork = function( function updateForwardRef(current, workInProgress) { var render = workInProgress.type.render; - var nextProps = workInProgress.pendingProps; - var ref = workInProgress.ref; - if (hasLegacyContextChanged()) { - // Normally we can bail out on props equality but if context has changed - // we don't do the bailout and we have to reuse existing props instead. - } else if (workInProgress.memoizedProps === nextProps) { - var currentRef = current !== null ? current.ref : null; - if (ref === currentRef) { - return bailoutOnAlreadyFinishedWork(current, workInProgress); - } - } - var nextChildren = render(nextProps, ref); + var nextChildren = render(workInProgress.pendingProps, workInProgress.ref); reconcileChildren(current, workInProgress, nextChildren); - memoizeProps(workInProgress, nextProps); + memoizeProps(workInProgress, nextChildren); return workInProgress.child; } @@ -8108,11 +8010,7 @@ var ReactFiberBeginWork = function( if (current === null) { if (workInProgress.stateNode === null) { // In the initial pass we might need to construct the instance. - constructClassInstance( - workInProgress, - workInProgress.pendingProps, - renderExpirationTime - ); + constructClassInstance(workInProgress, workInProgress.pendingProps); mountClassInstance(workInProgress, renderExpirationTime); shouldUpdate = true; @@ -8130,11 +8028,22 @@ var ReactFiberBeginWork = function( renderExpirationTime ); } + + // We processed the update queue inside updateClassInstance. It may have + // included some errors that were dispatched during the commit phase. + // TODO: Refactor class components so this is less awkward. + var didCaptureError = false; + var updateQueue = workInProgress.updateQueue; + if (updateQueue !== null && updateQueue.capturedValues !== null) { + shouldUpdate = true; + didCaptureError = true; + } return finishClassComponent( current, workInProgress, shouldUpdate, hasContext, + didCaptureError, renderExpirationTime ); } @@ -8144,13 +8053,12 @@ var ReactFiberBeginWork = function( workInProgress, shouldUpdate, hasContext, + didCaptureError, renderExpirationTime ) { // Refs should update even if shouldComponentUpdate returns false markRef(current, workInProgress); - var didCaptureError = (workInProgress.effectTag & DidCapture) !== NoEffect; - if (!shouldUpdate && !didCaptureError) { // Context providers should defer to sCU for rendering if (hasContext) { @@ -8246,26 +8154,29 @@ var ReactFiberBeginWork = function( pushHostRootContext(workInProgress); var updateQueue = workInProgress.updateQueue; if (updateQueue !== null) { - var nextProps = workInProgress.pendingProps; var prevState = workInProgress.memoizedState; - var prevChildren = prevState !== null ? prevState.element : null; - processUpdateQueue( + var state = processUpdateQueue( + current, workInProgress, updateQueue, - nextProps, + null, null, renderExpirationTime ); - var nextState = workInProgress.memoizedState; - // Caution: React DevTools currently depends on this property - // being called "element". - var nextChildren = nextState.element; + memoizeState(workInProgress, state); + updateQueue = workInProgress.updateQueue; - if (nextChildren === prevChildren) { + var element = void 0; + if (updateQueue !== null && updateQueue.capturedValues !== null) { + // There's an uncaught error. Unmount the whole root. + element = null; + } else if (prevState === state) { // If the state is the same as before, that's a bailout because we had // no work that expires at this time. resetHydrationState(); return bailoutOnAlreadyFinishedWork(current, workInProgress); + } else { + element = state.element; } var root = workInProgress.stateNode; if ( @@ -8290,15 +8201,16 @@ var ReactFiberBeginWork = function( workInProgress.child = mountChildFibers( workInProgress, null, - nextChildren, + element, renderExpirationTime ); } else { // Otherwise reset hydration state in case we aborted and resumed another // root. resetHydrationState(); - reconcileChildren(current, workInProgress, nextChildren); + reconcileChildren(current, workInProgress, element); } + memoizeState(workInProgress, state); return workInProgress.child; } resetHydrationState(); @@ -8434,13 +8346,21 @@ var ReactFiberBeginWork = function( workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null; - var getDerivedStateFromProps = Component.getDerivedStateFromProps; - if (typeof getDerivedStateFromProps === "function") { - applyDerivedStateFromProps( + if (typeof Component.getDerivedStateFromProps === "function") { + var partialState = callGetDerivedStateFromProps( workInProgress, - getDerivedStateFromProps, - props + value, + props, + workInProgress.memoizedState ); + + if (partialState !== null && partialState !== undefined) { + workInProgress.memoizedState = Object.assign( + {}, + workInProgress.memoizedState, + partialState + ); + } } // Push context providers early to prevent context stack mismatches. @@ -8454,6 +8374,7 @@ var ReactFiberBeginWork = function( workInProgress, true, hasContext, + false, renderExpirationTime ); } else { @@ -8599,7 +8520,7 @@ var ReactFiberBeginWork = function( var fiber = workInProgress.child; if (fiber !== null) { // Set the return pointer of the child to the work-in-progress fiber. - fiber.return = workInProgress; + fiber["return"] = workInProgress; } while (fiber !== null) { var nextFiber = void 0; @@ -8637,7 +8558,7 @@ var ReactFiberBeginWork = function( // ancestor path already has sufficient priority. break; } - node = node.return; + node = node["return"]; } // Don't scan deeper than a matching consumer. When we render the // consumer, we'll continue scanning from that point. This way the @@ -8659,7 +8580,7 @@ var ReactFiberBeginWork = function( } if (nextFiber !== null) { // Set the return pointer of the child to the work-in-progress fiber. - nextFiber.return = fiber; + nextFiber["return"] = fiber; } else { // No child. Traverse to next sibling. nextFiber = fiber; @@ -8671,13 +8592,11 @@ var ReactFiberBeginWork = function( } var sibling = nextFiber.sibling; if (sibling !== null) { - // Set the return pointer of the sibling to the work-in-progress fiber. - sibling.return = nextFiber.return; nextFiber = sibling; break; } // No more siblings. Traverse up. - nextFiber = nextFiber.return; + nextFiber = nextFiber["return"]; } } fiber = nextFiber; @@ -8694,10 +8613,8 @@ var ReactFiberBeginWork = function( var newProps = workInProgress.pendingProps; var oldProps = workInProgress.memoizedProps; - var canBailOnProps = true; if (hasLegacyContextChanged()) { - canBailOnProps = false; // Normally we can bail out on props equality but if context has changed // we don't do the bailout and we have to reuse existing props instead. } else if (oldProps === newProps) { @@ -8709,20 +8626,6 @@ var ReactFiberBeginWork = function( var newValue = newProps.value; workInProgress.memoizedProps = newProps; - { - var providerPropTypes = workInProgress.type.propTypes; - - if (providerPropTypes) { - checkPropTypes( - providerPropTypes, - newProps, - "prop", - "Context.Provider", - getCurrentFiberStackAddendum - ); - } - } - var changedBits = void 0; if (oldProps === null) { // Initial render @@ -8730,7 +8633,7 @@ var ReactFiberBeginWork = function( } else { if (oldProps.value === newProps.value) { // No change. Bailout early if children are the same. - if (oldProps.children === newProps.children && canBailOnProps) { + if (oldProps.children === newProps.children) { workInProgress.stateNode = 0; pushProvider(workInProgress); return bailoutOnAlreadyFinishedWork(current, workInProgress); @@ -8747,7 +8650,7 @@ var ReactFiberBeginWork = function( (oldValue !== oldValue && newValue !== newValue) // eslint-disable-line no-self-compare ) { // No change. Bailout early if children are the same. - if (oldProps.children === newProps.children && canBailOnProps) { + if (oldProps.children === newProps.children) { workInProgress.stateNode = 0; pushProvider(workInProgress); return bailoutOnAlreadyFinishedWork(current, workInProgress); @@ -8772,7 +8675,7 @@ var ReactFiberBeginWork = function( if (changedBits === 0) { // No change. Bailout early if children are the same. - if (oldProps.children === newProps.children && canBailOnProps) { + if (oldProps.children === newProps.children) { workInProgress.stateNode = 0; pushProvider(workInProgress); return bailoutOnAlreadyFinishedWork(current, workInProgress); @@ -8858,8 +8761,6 @@ var ReactFiberBeginWork = function( } var newChildren = render(newValue); - // React DevTools reads this flag. - workInProgress.effectTag |= PerformedWork; reconcileChildren(current, workInProgress, newChildren); return workInProgress.child; } @@ -9067,7 +8968,7 @@ var ReactFiberCompleteWork = function( function appendAllReturns(returns, workInProgress) { var node = workInProgress.stateNode; if (node) { - node.return = workInProgress; + node["return"] = workInProgress; } while (node !== null) { if ( @@ -9079,17 +8980,17 @@ var ReactFiberCompleteWork = function( } else if (node.tag === ReturnComponent) { returns.push(node.pendingProps.value); } else if (node.child !== null) { - node.child.return = node; + node.child["return"] = node; node = node.child; continue; } while (node.sibling === null) { - if (node.return === null || node.return === workInProgress) { + if (node["return"] === null || node["return"] === workInProgress) { return; } - node = node.return; + node = node["return"]; } - node.sibling.return = node.return; + node.sibling["return"] = node["return"]; node = node.sibling; } } @@ -9145,7 +9046,7 @@ var ReactFiberCompleteWork = function( // down its children. Instead, we'll get insertions from each child in // the portal directly. } else if (node.child !== null) { - node.child.return = node; + node.child["return"] = node; node = node.child; continue; } @@ -9153,12 +9054,12 @@ var ReactFiberCompleteWork = function( return; } while (node.sibling === null) { - if (node.return === null || node.return === workInProgress) { + if (node["return"] === null || node["return"] === workInProgress) { return; } - node = node.return; + node = node["return"]; } - node.sibling.return = node.return; + node.sibling["return"] = node["return"]; node = node.sibling; } } @@ -9225,7 +9126,7 @@ var ReactFiberCompleteWork = function( // down its children. Instead, we'll get insertions from each child in // the portal directly. } else if (node.child !== null) { - node.child.return = node; + node.child["return"] = node; node = node.child; continue; } @@ -9233,12 +9134,12 @@ var ReactFiberCompleteWork = function( return; } while (node.sibling === null) { - if (node.return === null || node.return === workInProgress) { + if (node["return"] === null || node["return"] === workInProgress) { return; } - node = node.return; + node = node["return"]; } - node.sibling.return = node.return; + node.sibling["return"] = node["return"]; node = node.sibling; } }; @@ -9364,6 +9265,20 @@ var ReactFiberCompleteWork = function( case ClassComponent: { // We are leaving this subtree, so pop context if any. popLegacyContextProvider(workInProgress); + + // If this component caught an error, schedule an error log effect. + var instance = workInProgress.stateNode; + var updateQueue = workInProgress.updateQueue; + if (updateQueue !== null && updateQueue.capturedValues !== null) { + workInProgress.effectTag &= ~DidCapture; + if (typeof instance.componentDidCatch === "function") { + workInProgress.effectTag |= ErrLog; + } else { + // Normally we clear this in the commit phase, but since we did not + // schedule an effect, we need to reset it here. + updateQueue.capturedValues = null; + } + } return null; } case HostRoot: { @@ -9383,6 +9298,11 @@ var ReactFiberCompleteWork = function( workInProgress.effectTag &= ~Placement; } updateHostContainer(workInProgress); + + var _updateQueue = workInProgress.updateQueue; + if (_updateQueue !== null && _updateQueue.capturedValues !== null) { + workInProgress.effectTag |= ErrLog; + } return null; } case HostComponent: { @@ -9397,13 +9317,13 @@ var ReactFiberCompleteWork = function( // have newProps so we'll have to reuse them. // TODO: Split the update API as separate for the props vs. children. // Even better would be if children weren't special cased at all tho. - var instance = workInProgress.stateNode; + var _instance = workInProgress.stateNode; var currentHostContext = getHostContext(); // TODO: Experiencing an error where oldProps is null. Suggests a host // component is hitting the resume path. Figure out why. Possibly // related to `hidden`. var updatePayload = prepareUpdate( - instance, + _instance, type, oldProps, newProps, @@ -9457,7 +9377,7 @@ var ReactFiberCompleteWork = function( markUpdate(workInProgress); } } else { - var _instance = createInstance( + var _instance2 = createInstance( type, newProps, rootContainerInstance, @@ -9465,14 +9385,14 @@ var ReactFiberCompleteWork = function( workInProgress ); - appendAllChildren(_instance, workInProgress); + appendAllChildren(_instance2, workInProgress); // Certain renderers require commit-time effects for initial mount. // (eg DOM renderer supports auto-focus for certain elements). // Make sure such renderers get scheduled for later work. if ( finalizeInitialChildren( - _instance, + _instance2, type, newProps, rootContainerInstance, @@ -9481,7 +9401,7 @@ var ReactFiberCompleteWork = function( ) { markUpdate(workInProgress); } - workInProgress.stateNode = _instance; + workInProgress.stateNode = _instance2; } if (workInProgress.ref !== null) { @@ -9588,6 +9508,139 @@ function createCapturedValue(value, source) { }; } +var ReactFiberUnwindWork = function( + hostContext, + legacyContext, + newContext, + scheduleWork, + isAlreadyFailedLegacyErrorBoundary +) { + var popHostContainer = hostContext.popHostContainer, + popHostContext = hostContext.popHostContext; + var popLegacyContextProvider = legacyContext.popContextProvider, + popTopLevelLegacyContextObject = legacyContext.popTopLevelContextObject; + var popProvider = newContext.popProvider; + + function throwException(returnFiber, sourceFiber, rawValue) { + // The source fiber did not complete. + sourceFiber.effectTag |= Incomplete; + // Its effect list is no longer valid. + sourceFiber.firstEffect = sourceFiber.lastEffect = null; + + var value = createCapturedValue(rawValue, sourceFiber); + + var workInProgress = returnFiber; + do { + switch (workInProgress.tag) { + case HostRoot: { + // Uncaught error + var errorInfo = value; + ensureUpdateQueues(workInProgress); + var updateQueue = workInProgress.updateQueue; + updateQueue.capturedValues = [errorInfo]; + workInProgress.effectTag |= ShouldCapture; + return; + } + case ClassComponent: + // Capture and retry + var ctor = workInProgress.type; + var _instance = workInProgress.stateNode; + if ( + (workInProgress.effectTag & DidCapture) === NoEffect && + ((typeof ctor.getDerivedStateFromCatch === "function" && + enableGetDerivedStateFromCatch) || + (_instance !== null && + typeof _instance.componentDidCatch === "function" && + !isAlreadyFailedLegacyErrorBoundary(_instance))) + ) { + ensureUpdateQueues(workInProgress); + var _updateQueue = workInProgress.updateQueue; + var capturedValues = _updateQueue.capturedValues; + if (capturedValues === null) { + _updateQueue.capturedValues = [value]; + } else { + capturedValues.push(value); + } + workInProgress.effectTag |= ShouldCapture; + return; + } + break; + default: + break; + } + workInProgress = workInProgress["return"]; + } while (workInProgress !== null); + } + + function unwindWork(workInProgress) { + switch (workInProgress.tag) { + case ClassComponent: { + popLegacyContextProvider(workInProgress); + var effectTag = workInProgress.effectTag; + if (effectTag & ShouldCapture) { + workInProgress.effectTag = (effectTag & ~ShouldCapture) | DidCapture; + return workInProgress; + } + return null; + } + case HostRoot: { + popHostContainer(workInProgress); + popTopLevelLegacyContextObject(workInProgress); + var _effectTag = workInProgress.effectTag; + if (_effectTag & ShouldCapture) { + workInProgress.effectTag = (_effectTag & ~ShouldCapture) | DidCapture; + return workInProgress; + } + return null; + } + case HostComponent: { + popHostContext(workInProgress); + return null; + } + case HostPortal: + popHostContainer(workInProgress); + return null; + case ContextProvider: + popProvider(workInProgress); + return null; + default: + return null; + } + } + + function unwindInterruptedWork(interruptedWork) { + switch (interruptedWork.tag) { + case ClassComponent: { + popLegacyContextProvider(interruptedWork); + break; + } + case HostRoot: { + popHostContainer(interruptedWork); + popTopLevelLegacyContextObject(interruptedWork); + break; + } + case HostComponent: { + popHostContext(interruptedWork); + break; + } + case HostPortal: + popHostContainer(interruptedWork); + break; + case ContextProvider: + popProvider(interruptedWork); + break; + default: + break; + } + } + + return { + throwException: throwException, + unwindWork: unwindWork, + unwindInterruptedWork: unwindInterruptedWork + }; +}; + // This module is forked in different environments. // By default, return `true` to log errors to the console. // Forks can return `false` if this isn't desirable. @@ -9839,14 +9892,7 @@ var ReactFiberCommitWork = function( } var updateQueue = finishedWork.updateQueue; if (updateQueue !== null) { - _instance2.props = finishedWork.memoizedProps; - _instance2.state = finishedWork.memoizedState; - commitUpdateQueue( - finishedWork, - updateQueue, - _instance2, - committedExpirationTime - ); + commitCallbacks(updateQueue, _instance2); } return; } @@ -9864,12 +9910,7 @@ var ReactFiberCommitWork = function( break; } } - commitUpdateQueue( - finishedWork, - _updateQueue, - _instance3, - committedExpirationTime - ); + commitCallbacks(_updateQueue, _instance3); } return; } @@ -9906,17 +9947,81 @@ var ReactFiberCommitWork = function( } } + function commitErrorLogging(finishedWork, onUncaughtError) { + switch (finishedWork.tag) { + case ClassComponent: + { + var ctor = finishedWork.type; + var _instance5 = finishedWork.stateNode; + var updateQueue = finishedWork.updateQueue; + invariant( + updateQueue !== null && updateQueue.capturedValues !== null, + "An error logging effect should not have been scheduled if no errors " + + "were captured. This error is likely caused by a bug in React. " + + "Please file an issue." + ); + var capturedErrors = updateQueue.capturedValues; + updateQueue.capturedValues = null; + + if (typeof ctor.getDerivedStateFromCatch !== "function") { + // To preserve the preexisting retry behavior of error boundaries, + // we keep track of which ones already failed during this batch. + // This gets reset before we yield back to the browser. + // TODO: Warn in strict mode if getDerivedStateFromCatch is + // not defined. + markLegacyErrorBoundaryAsFailed(_instance5); + } + + _instance5.props = finishedWork.memoizedProps; + _instance5.state = finishedWork.memoizedState; + for (var i = 0; i < capturedErrors.length; i++) { + var errorInfo = capturedErrors[i]; + var _error = errorInfo.value; + var stack = errorInfo.stack; + logError(finishedWork, errorInfo); + _instance5.componentDidCatch(_error, { + componentStack: stack !== null ? stack : "" + }); + } + } + break; + case HostRoot: { + var _updateQueue2 = finishedWork.updateQueue; + invariant( + _updateQueue2 !== null && _updateQueue2.capturedValues !== null, + "An error logging effect should not have been scheduled if no errors " + + "were captured. This error is likely caused by a bug in React. " + + "Please file an issue." + ); + var _capturedErrors = _updateQueue2.capturedValues; + _updateQueue2.capturedValues = null; + for (var _i = 0; _i < _capturedErrors.length; _i++) { + var _errorInfo = _capturedErrors[_i]; + logError(finishedWork, _errorInfo); + onUncaughtError(_errorInfo.value); + } + break; + } + default: + invariant( + false, + "This unit of work tag cannot capture errors. This error is " + + "likely caused by a bug in React. Please file an issue." + ); + } + } + function commitAttachRef(finishedWork) { var ref = finishedWork.ref; if (ref !== null) { - var _instance5 = finishedWork.stateNode; + var _instance6 = finishedWork.stateNode; var instanceToUse = void 0; switch (finishedWork.tag) { case HostComponent: - instanceToUse = getPublicInstance(_instance5); + instanceToUse = getPublicInstance(_instance6); break; default: - instanceToUse = _instance5; + instanceToUse = _instance6; } if (typeof ref === "function") { ref(instanceToUse); @@ -9960,9 +10065,9 @@ var ReactFiberCommitWork = function( switch (current.tag) { case ClassComponent: { safelyDetachRef(current); - var _instance6 = current.stateNode; - if (typeof _instance6.componentWillUnmount === "function") { - safelyCallComponentWillUnmount(current, _instance6); + var _instance7 = current.stateNode; + if (typeof _instance7.componentWillUnmount === "function") { + safelyCallComponentWillUnmount(current, _instance7); } return; } @@ -10004,7 +10109,7 @@ var ReactFiberCommitWork = function( // If we don't use mutation we drill down into portals here instead. (!mutation || node.tag !== HostPortal) ) { - node.child.return = node; + node.child["return"] = node; node = node.child; continue; } @@ -10012,12 +10117,12 @@ var ReactFiberCommitWork = function( return; } while (node.sibling === null) { - if (node.return === null || node.return === root) { + if (node["return"] === null || node["return"] === root) { return; } - node = node.return; + node = node["return"]; } - node.sibling.return = node.return; + node.sibling["return"] = node["return"]; node = node.sibling; } } @@ -10028,11 +10133,11 @@ var ReactFiberCommitWork = function( // get GC:ed but we don't know which for sure which parent is the current // one so we'll settle for GC:ing the subtree of this child. This child // itself will be GC:ed when the parent updates the next time. - current.return = null; + current["return"] = null; current.child = null; if (current.alternate) { current.alternate.child = null; - current.alternate.return = null; + current.alternate["return"] = null; } } @@ -10100,6 +10205,7 @@ var ReactFiberCommitWork = function( commitLifeCycles: commitLifeCycles, commitBeforeMutationLifeCycles: commitBeforeMutationLifeCycles, + commitErrorLogging: commitErrorLogging, commitAttachRef: commitAttachRef, commitDetachRef: commitDetachRef }; @@ -10121,12 +10227,12 @@ var ReactFiberCommitWork = function( removeChildFromContainer = mutation.removeChildFromContainer; function getHostParentFiber(fiber) { - var parent = fiber.return; + var parent = fiber["return"]; while (parent !== null) { if (isHostParent(parent)) { return parent; } - parent = parent.return; + parent = parent["return"]; } invariant( false, @@ -10151,14 +10257,14 @@ var ReactFiberCommitWork = function( siblings: while (true) { // If we didn't find anything, let's try the next sibling. while (node.sibling === null) { - if (node.return === null || isHostParent(node.return)) { + if (node["return"] === null || isHostParent(node["return"])) { // If we pop out of the root or hit the parent the fiber we are the // last sibling. return null; } - node = node.return; + node = node["return"]; } - node.sibling.return = node.return; + node.sibling["return"] = node["return"]; node = node.sibling; while (node.tag !== HostComponent && node.tag !== HostText) { // If it is not host node and, we might have a host node inside it. @@ -10172,7 +10278,7 @@ var ReactFiberCommitWork = function( if (node.child === null || node.tag === HostPortal) { continue siblings; } else { - node.child.return = node; + node.child["return"] = node; node = node.child; } } @@ -10240,7 +10346,7 @@ var ReactFiberCommitWork = function( // down its children. Instead, we'll get insertions from each child in // the portal directly. } else if (node.child !== null) { - node.child.return = node; + node.child["return"] = node; node = node.child; continue; } @@ -10248,12 +10354,12 @@ var ReactFiberCommitWork = function( return; } while (node.sibling === null) { - if (node.return === null || node.return === finishedWork) { + if (node["return"] === null || node["return"] === finishedWork) { return; } - node = node.return; + node = node["return"]; } - node.sibling.return = node.return; + node.sibling["return"] = node["return"]; node = node.sibling; } } @@ -10270,7 +10376,7 @@ var ReactFiberCommitWork = function( while (true) { if (!currentParentIsValid) { - var parent = node.return; + var parent = node["return"]; findParent: while (true) { invariant( parent !== null, @@ -10291,7 +10397,7 @@ var ReactFiberCommitWork = function( currentParentIsContainer = true; break findParent; } - parent = parent.return; + parent = parent["return"]; } currentParentIsValid = true; } @@ -10312,7 +10418,7 @@ var ReactFiberCommitWork = function( currentParent = node.stateNode.containerInfo; // Visit children because portals might contain host components. if (node.child !== null) { - node.child.return = node; + node.child["return"] = node; node = node.child; continue; } @@ -10320,7 +10426,7 @@ var ReactFiberCommitWork = function( commitUnmount(node); // Visit children because we may find more host components below. if (node.child !== null) { - node.child.return = node; + node.child["return"] = node; node = node.child; continue; } @@ -10329,17 +10435,17 @@ var ReactFiberCommitWork = function( return; } while (node.sibling === null) { - if (node.return === null || node.return === current) { + if (node["return"] === null || node["return"] === current) { return; } - node = node.return; + node = node["return"]; if (node.tag === HostPortal) { // When we go out of the portal, we need to restore the parent. // Since we don't keep a stack of them, we will search for it. currentParentIsValid = false; } } - node.sibling.return = node.return; + node.sibling["return"] = node["return"]; node = node.sibling; } } @@ -10357,8 +10463,8 @@ var ReactFiberCommitWork = function( return; } case HostComponent: { - var _instance7 = finishedWork.stateNode; - if (_instance7 != null) { + var _instance8 = finishedWork.stateNode; + if (_instance8 != null) { // Commit the work prepared earlier. var newProps = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps @@ -10371,7 +10477,7 @@ var ReactFiberCommitWork = function( finishedWork.updateQueue = null; if (updatePayload !== null) { commitUpdate( - _instance7, + _instance8, updatePayload, type, oldProps, @@ -10422,6 +10528,7 @@ var ReactFiberCommitWork = function( commitDeletion: commitDeletion, commitWork: commitWork, commitLifeCycles: commitLifeCycles, + commitErrorLogging: commitErrorLogging, commitAttachRef: commitAttachRef, commitDetachRef: commitDetachRef }; @@ -10430,208 +10537,6 @@ var ReactFiberCommitWork = function( } }; -var ReactFiberUnwindWork = function( - hostContext, - legacyContext, - newContext, - scheduleWork, - markLegacyErrorBoundaryAsFailed, - isAlreadyFailedLegacyErrorBoundary, - onUncaughtError -) { - var popHostContainer = hostContext.popHostContainer, - popHostContext = hostContext.popHostContext; - var popLegacyContextProvider = legacyContext.popContextProvider, - popTopLevelLegacyContextObject = legacyContext.popTopLevelContextObject; - var popProvider = newContext.popProvider; - - function createRootErrorUpdate(fiber, errorInfo, expirationTime) { - var update = createUpdate(expirationTime); - // Unmount the root by rendering null. - update.tag = CaptureUpdate; - // Caution: React DevTools currently depends on this property - // being called "element". - update.payload = { element: null }; - var error = errorInfo.value; - update.callback = function() { - onUncaughtError(error); - logError(fiber, errorInfo); - }; - return update; - } - - function createClassErrorUpdate(fiber, errorInfo, expirationTime) { - var update = createUpdate(expirationTime); - update.tag = CaptureUpdate; - var getDerivedStateFromCatch = fiber.type.getDerivedStateFromCatch; - if ( - enableGetDerivedStateFromCatch && - typeof getDerivedStateFromCatch === "function" - ) { - var _error = errorInfo.value; - update.payload = function() { - return getDerivedStateFromCatch(_error); - }; - } - - var inst = fiber.stateNode; - if (inst !== null && typeof inst.componentDidCatch === "function") { - update.callback = function callback() { - if ( - !enableGetDerivedStateFromCatch || - getDerivedStateFromCatch !== "function" - ) { - // To preserve the preexisting retry behavior of error boundaries, - // we keep track of which ones already failed during this batch. - // This gets reset before we yield back to the browser. - // TODO: Warn in strict mode if getDerivedStateFromCatch is - // not defined. - markLegacyErrorBoundaryAsFailed(this); - } - var error = errorInfo.value; - var stack = errorInfo.stack; - logError(fiber, errorInfo); - this.componentDidCatch(error, { - componentStack: stack !== null ? stack : "" - }); - }; - } - return update; - } - - function throwException( - returnFiber, - sourceFiber, - rawValue, - renderExpirationTime - ) { - // The source fiber did not complete. - sourceFiber.effectTag |= Incomplete; - // Its effect list is no longer valid. - sourceFiber.firstEffect = sourceFiber.lastEffect = null; - - var value = createCapturedValue(rawValue, sourceFiber); - - var workInProgress = returnFiber; - do { - switch (workInProgress.tag) { - case HostRoot: { - var _errorInfo = value; - workInProgress.effectTag |= ShouldCapture; - var update = createRootErrorUpdate( - workInProgress, - _errorInfo, - renderExpirationTime - ); - enqueueCapturedUpdate(workInProgress, update, renderExpirationTime); - return; - } - case ClassComponent: - // Capture and retry - var errorInfo = value; - var ctor = workInProgress.type; - var _instance = workInProgress.stateNode; - if ( - (workInProgress.effectTag & DidCapture) === NoEffect && - ((typeof ctor.getDerivedStateFromCatch === "function" && - enableGetDerivedStateFromCatch) || - (_instance !== null && - typeof _instance.componentDidCatch === "function" && - !isAlreadyFailedLegacyErrorBoundary(_instance))) - ) { - workInProgress.effectTag |= ShouldCapture; - // Schedule the error boundary to re-render using updated state - var _update = createClassErrorUpdate( - workInProgress, - errorInfo, - renderExpirationTime - ); - enqueueCapturedUpdate( - workInProgress, - _update, - renderExpirationTime - ); - return; - } - break; - default: - break; - } - workInProgress = workInProgress.return; - } while (workInProgress !== null); - } - - function unwindWork(workInProgress) { - switch (workInProgress.tag) { - case ClassComponent: { - popLegacyContextProvider(workInProgress); - var effectTag = workInProgress.effectTag; - if (effectTag & ShouldCapture) { - workInProgress.effectTag = (effectTag & ~ShouldCapture) | DidCapture; - return workInProgress; - } - return null; - } - case HostRoot: { - popHostContainer(workInProgress); - popTopLevelLegacyContextObject(workInProgress); - var _effectTag = workInProgress.effectTag; - if (_effectTag & ShouldCapture) { - workInProgress.effectTag = (_effectTag & ~ShouldCapture) | DidCapture; - return workInProgress; - } - return null; - } - case HostComponent: { - popHostContext(workInProgress); - return null; - } - case HostPortal: - popHostContainer(workInProgress); - return null; - case ContextProvider: - popProvider(workInProgress); - return null; - default: - return null; - } - } - - function unwindInterruptedWork(interruptedWork) { - switch (interruptedWork.tag) { - case ClassComponent: { - popLegacyContextProvider(interruptedWork); - break; - } - case HostRoot: { - popHostContainer(interruptedWork); - popTopLevelLegacyContextObject(interruptedWork); - break; - } - case HostComponent: { - popHostContext(interruptedWork); - break; - } - case HostPortal: - popHostContainer(interruptedWork); - break; - case ContextProvider: - popProvider(interruptedWork); - break; - default: - break; - } - } - - return { - throwException: throwException, - unwindWork: unwindWork, - unwindInterruptedWork: unwindInterruptedWork, - createRootErrorUpdate: createRootErrorUpdate, - createClassErrorUpdate: createClassErrorUpdate - }; -}; - var NO_CONTEXT = {}; var ReactFiberHostContext = function(config, stack) { @@ -10816,7 +10721,7 @@ var ReactFiberHydrationContext = function(config) { var childToDelete = createFiberFromHostInstanceForDeletion(); childToDelete.stateNode = instance; - childToDelete.return = returnFiber; + childToDelete["return"] = returnFiber; childToDelete.effectTag = Deletion; // This might seem like it belongs on progressedFirstDeletion. However, @@ -11014,13 +10919,13 @@ var ReactFiberHydrationContext = function(config) { } function popToNextHostParent(fiber) { - var parent = fiber.return; + var parent = fiber["return"]; while ( parent !== null && parent.tag !== HostComponent && parent.tag !== HostRoot ) { - parent = parent.return; + parent = parent["return"]; } hydrationParentFiber = parent; } @@ -11342,7 +11247,7 @@ var ReactFiberLegacyContext = function(stack) { if (isContextProvider(node)) { return node.stateNode.__reactInternalMemoizedMergedChildContext; } - var parent = node.return; + var parent = node["return"]; invariant( parent, "Found unexpected detached subtree parent. " + @@ -11615,15 +11520,11 @@ var ReactFiberScheduler = function(config) { legacyContext, newContext, scheduleWork, - markLegacyErrorBoundaryAsFailed, - isAlreadyFailedLegacyErrorBoundary, - onUncaughtError + isAlreadyFailedLegacyErrorBoundary ), throwException = _ReactFiberUnwindWork.throwException, unwindWork = _ReactFiberUnwindWork.unwindWork, - unwindInterruptedWork = _ReactFiberUnwindWork.unwindInterruptedWork, - createRootErrorUpdate = _ReactFiberUnwindWork.createRootErrorUpdate, - createClassErrorUpdate = _ReactFiberUnwindWork.createClassErrorUpdate; + unwindInterruptedWork = _ReactFiberUnwindWork.unwindInterruptedWork; var _ReactFiberCommitWork = ReactFiberCommitWork( config, @@ -11640,6 +11541,7 @@ var ReactFiberScheduler = function(config) { commitDeletion = _ReactFiberCommitWork.commitDeletion, commitWork = _ReactFiberCommitWork.commitWork, commitLifeCycles = _ReactFiberCommitWork.commitLifeCycles, + commitErrorLogging = _ReactFiberCommitWork.commitErrorLogging, commitAttachRef = _ReactFiberCommitWork.commitAttachRef, commitDetachRef = _ReactFiberCommitWork.commitDetachRef; @@ -11737,10 +11639,10 @@ var ReactFiberScheduler = function(config) { function resetStack() { if (nextUnitOfWork !== null) { - var interruptedWork = nextUnitOfWork.return; + var interruptedWork = nextUnitOfWork["return"]; while (interruptedWork !== null) { unwindInterruptedWork(interruptedWork); - interruptedWork = interruptedWork.return; + interruptedWork = interruptedWork["return"]; } } @@ -11865,6 +11767,10 @@ var ReactFiberScheduler = function(config) { ); } + if (effectTag & ErrLog) { + commitErrorLogging(nextEffect, onUncaughtError); + } + if (effectTag & Ref) { recordEffect(); commitAttachRef(nextEffect); @@ -12071,16 +11977,7 @@ var ReactFiberScheduler = function(config) { } // Check for pending updates. - var newExpirationTime = NoWork; - switch (workInProgress.tag) { - case HostRoot: - case ClassComponent: { - var updateQueue = workInProgress.updateQueue; - if (updateQueue !== null) { - newExpirationTime = updateQueue.expirationTime; - } - } - } + var newExpirationTime = getUpdateExpirationTime(workInProgress); // TODO: Calls need to visit stateNode @@ -12113,7 +12010,7 @@ var ReactFiberScheduler = function(config) { ReactDebugCurrentFiber.setCurrentFiber(workInProgress); } - var returnFiber = workInProgress.return; + var returnFiber = workInProgress["return"]; var siblingFiber = workInProgress.sibling; if ((workInProgress.effectTag & Incomplete) === NoEffect) { @@ -12355,19 +12252,13 @@ var ReactFiberScheduler = function(config) { break; } - { - // Reset global debug state - // We assume this is defined in DEV - resetCurrentlyProcessingQueue(); - } - if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) { var failedUnitOfWork = nextUnitOfWork; replayUnitOfWork(failedUnitOfWork, thrownValue, isAsync); } var sourceFiber = nextUnitOfWork; - var returnFiber = sourceFiber.return; + var returnFiber = sourceFiber["return"]; if (returnFiber === null) { // This is the root. The root could capture its own errors. However, // we don't know if it errors before or after we pushed the host @@ -12379,12 +12270,7 @@ var ReactFiberScheduler = function(config) { onUncaughtError(thrownValue); break; } - throwException( - returnFiber, - sourceFiber, - thrownValue, - nextRenderExpirationTime - ); + throwException(returnFiber, sourceFiber, thrownValue); nextUnitOfWork = completeUnitOfWork(sourceFiber); } break; @@ -12432,13 +12318,31 @@ var ReactFiberScheduler = function(config) { } } + function scheduleCapture(sourceFiber, boundaryFiber, value, expirationTime) { + // TODO: We only support dispatching errors. + var capturedValue = createCapturedValue(value, sourceFiber); + var update = { + expirationTime: expirationTime, + partialState: null, + callback: null, + isReplace: false, + isForced: false, + capturedValue: capturedValue, + next: null + }; + insertUpdateIntoFiber(boundaryFiber, update); + scheduleWork(boundaryFiber, expirationTime); + } + function dispatch(sourceFiber, value, expirationTime) { invariant( !isWorking || isCommitting, "dispatch: Cannot dispatch during the render phase." ); - var fiber = sourceFiber.return; + // TODO: Handle arrays + + var fiber = sourceFiber["return"]; while (fiber !== null) { switch (fiber.tag) { case ClassComponent: @@ -12449,44 +12353,22 @@ var ReactFiberScheduler = function(config) { (typeof instance.componentDidCatch === "function" && !isAlreadyFailedLegacyErrorBoundary(instance)) ) { - var errorInfo = createCapturedValue(value, sourceFiber); - var update = createClassErrorUpdate( - fiber, - errorInfo, - expirationTime - ); - enqueueUpdate(fiber, update, expirationTime); - scheduleWork(fiber, expirationTime); + scheduleCapture(sourceFiber, fiber, value, expirationTime); return; } break; - case HostRoot: { - var _errorInfo = createCapturedValue(value, sourceFiber); - var _update = createRootErrorUpdate( - fiber, - _errorInfo, - expirationTime - ); - enqueueUpdate(fiber, _update, expirationTime); - scheduleWork(fiber, expirationTime); + // TODO: Handle async boundaries + case HostRoot: + scheduleCapture(sourceFiber, fiber, value, expirationTime); return; - } } - fiber = fiber.return; + fiber = fiber["return"]; } if (sourceFiber.tag === HostRoot) { // Error was thrown at the root. There is no parent, so the root // itself should capture it. - var rootFiber = sourceFiber; - var _errorInfo2 = createCapturedValue(value, rootFiber); - var _update2 = createRootErrorUpdate( - rootFiber, - _errorInfo2, - expirationTime - ); - enqueueUpdate(rootFiber, _update2, expirationTime); - scheduleWork(rootFiber, expirationTime); + scheduleCapture(sourceFiber, sourceFiber, value, expirationTime); } } @@ -12614,7 +12496,7 @@ var ReactFiberScheduler = function(config) { node.alternate.expirationTime = expirationTime; } } - if (node.return === null) { + if (node["return"] === null) { if (node.tag === HostRoot) { var root = node.stateNode; if ( @@ -12655,7 +12537,7 @@ var ReactFiberScheduler = function(config) { return; } } - node = node.return; + node = node["return"]; } } @@ -13284,14 +13166,9 @@ var ReactFiberReconciler$1 = function(config) { } } - var update = createUpdate(expirationTime); - // Caution: React DevTools currently depends on this property - // being called "element". - update.payload = { element: element }; - callback = callback === undefined ? null : callback; - if (callback !== null) { - !(typeof callback === "function") + { + !(callback === null || typeof callback === "function") ? warning( false, "render(...): Expected the last optional `callback` argument to be a " + @@ -13299,11 +13176,20 @@ var ReactFiberReconciler$1 = function(config) { callback ) : void 0; - update.callback = callback; } - enqueueUpdate(current, update, expirationTime); + var update = { + expirationTime: expirationTime, + partialState: { element: element }, + callback: callback, + isReplace: false, + isForced: false, + capturedValue: null, + next: null + }; + insertUpdateIntoFiber(current, update); scheduleWork(current, expirationTime); + return expirationTime; } @@ -13481,8 +13367,8 @@ var ReactFiberReconciler$3 = // TODO: decide on the top-level export form. // This is hacky but makes it work with both Rollup and Jest. -var reactReconciler = ReactFiberReconciler$3.default - ? ReactFiberReconciler$3.default +var reactReconciler = ReactFiberReconciler$3["default"] + ? ReactFiberReconciler$3["default"] : ReactFiberReconciler$3; function _classCallCheck$1(instance, Constructor) { @@ -13909,7 +13795,7 @@ var ReactFabric = { if (root) { // TODO: Is it safe to reset this now or should I wait since this unmount could be deferred? ReactFabricRenderer.updateContainer(null, root, null, function() { - roots.delete(containerTag); + roots["delete"](containerTag); }); } }, @@ -13966,7 +13852,9 @@ var ReactFabric$3 = (ReactFabric$2 && ReactFabric) || ReactFabric$2; // TODO: decide on the top-level export form. // This is hacky but makes it work with both Rollup and Jest. -var fabric = ReactFabric$3.default ? ReactFabric$3.default : ReactFabric$3; +var fabric = ReactFabric$3["default"] + ? ReactFabric$3["default"] + : ReactFabric$3; module.exports = fabric; diff --git a/Libraries/Renderer/oss/ReactFabric-prod.js b/Libraries/Renderer/oss/ReactFabric-prod.js index 32b02cc8387..19ca0dde9e3 100644 --- a/Libraries/Renderer/oss/ReactFabric-prod.js +++ b/Libraries/Renderer/oss/ReactFabric-prod.js @@ -5,7 +5,6 @@ * LICENSE file in the root directory of this source tree. * * @noflow - * @providesModule ReactFabric-prod * @preventMunge */ @@ -211,7 +210,7 @@ function getListener(inst, registrationName) { return listener; } function getParent(inst) { - do inst = inst.return; + do inst = inst["return"]; while (inst && 5 !== inst.tag); return inst ? inst : null; } @@ -918,17 +917,21 @@ injection.injectEventPluginsByName({ ResponderEventPlugin: ResponderEventPlugin, ReactNativeBridgeEventPlugin: ReactNativeBridgeEventPlugin }); -var hasSymbol = "function" === typeof Symbol && Symbol.for, - REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for("react.element") : 60103, - REACT_CALL_TYPE = hasSymbol ? Symbol.for("react.call") : 60104, - REACT_RETURN_TYPE = hasSymbol ? Symbol.for("react.return") : 60105, - REACT_PORTAL_TYPE = hasSymbol ? Symbol.for("react.portal") : 60106, - REACT_FRAGMENT_TYPE = hasSymbol ? Symbol.for("react.fragment") : 60107, - REACT_STRICT_MODE_TYPE = hasSymbol ? Symbol.for("react.strict_mode") : 60108, - REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for("react.provider") : 60109, - REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for("react.context") : 60110, - REACT_ASYNC_MODE_TYPE = hasSymbol ? Symbol.for("react.async_mode") : 60111, - REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for("react.forward_ref") : 60112, +var hasSymbol = "function" === typeof Symbol && Symbol["for"], + REACT_ELEMENT_TYPE = hasSymbol ? Symbol["for"]("react.element") : 60103, + REACT_CALL_TYPE = hasSymbol ? Symbol["for"]("react.call") : 60104, + REACT_RETURN_TYPE = hasSymbol ? Symbol["for"]("react.return") : 60105, + REACT_PORTAL_TYPE = hasSymbol ? Symbol["for"]("react.portal") : 60106, + REACT_FRAGMENT_TYPE = hasSymbol ? Symbol["for"]("react.fragment") : 60107, + REACT_STRICT_MODE_TYPE = hasSymbol + ? Symbol["for"]("react.strict_mode") + : 60108, + REACT_PROVIDER_TYPE = hasSymbol ? Symbol["for"]("react.provider") : 60109, + REACT_CONTEXT_TYPE = hasSymbol ? Symbol["for"]("react.context") : 60110, + REACT_ASYNC_MODE_TYPE = hasSymbol ? Symbol["for"]("react.async_mode") : 60111, + REACT_FORWARD_REF_TYPE = hasSymbol + ? Symbol["for"]("react.forward_ref") + : 60112, MAYBE_ITERATOR_SYMBOL = "function" === typeof Symbol && Symbol.iterator; function getIteratorFn(maybeIterable) { if (null === maybeIterable || "undefined" === typeof maybeIterable) @@ -1250,11 +1253,11 @@ function getComponentName(fiber) { } function isFiberMountedImpl(fiber) { var node = fiber; - if (fiber.alternate) for (; node.return; ) node = node.return; + if (fiber.alternate) for (; node["return"]; ) node = node["return"]; else { if (0 !== (node.effectTag & 2)) return 1; - for (; node.return; ) - if (((node = node.return), 0 !== (node.effectTag & 2))) return 1; + for (; node["return"]; ) + if (((node = node["return"]), 0 !== (node.effectTag & 2))) return 1; } return 3 === node.tag ? 2 : 3; } @@ -1281,7 +1284,7 @@ function findCurrentFiberUsingSlowPath(fiber) { 1 === alternate ? null : fiber ); for (var a = fiber, b = alternate; ; ) { - var parentA = a.return, + var parentA = a["return"], parentB = parentA ? parentA.alternate : null; if (!parentA || !parentB) break; if (parentA.child === parentB.child) { @@ -1292,7 +1295,7 @@ function findCurrentFiberUsingSlowPath(fiber) { } invariant(!1, "Unable to find node on an unmounted component."); } - if (a.return !== b.return) (a = parentA), (b = parentB); + if (a["return"] !== b["return"]) (a = parentA), (b = parentB); else { child = !1; for (var _child = parentA.child; _child; ) { @@ -1345,14 +1348,14 @@ function findCurrentHostFiber(parent) { if (!parent) return null; for (var node = parent; ; ) { if (5 === node.tag || 6 === node.tag) return node; - if (node.child) (node.child.return = node), (node = node.child); + if (node.child) (node.child["return"] = node), (node = node.child); else { if (node === parent) break; for (; !node.sibling; ) { - if (!node.return || node.return === parent) return null; - node = node.return; + if (!node["return"] || node["return"] === parent) return null; + node = node["return"]; } - node.sibling.return = node.return; + node.sibling["return"] = node["return"]; node = node.sibling; } } @@ -1364,14 +1367,14 @@ function findCurrentHostFiberWithNoPortals(parent) { for (var node = parent; ; ) { if (5 === node.tag || 6 === node.tag) return node; if (node.child && 4 !== node.tag) - (node.child.return = node), (node = node.child); + (node.child["return"] = node), (node = node.child); else { if (node === parent) break; for (; !node.sibling; ) { - if (!node.return || node.return === parent) return null; - node = node.return; + if (!node["return"] || node["return"] === parent) return null; + node = node["return"]; } - node.sibling.return = node.return; + node.sibling["return"] = node["return"]; node = node.sibling; } } @@ -1380,7 +1383,8 @@ function findCurrentHostFiberWithNoPortals(parent) { function FiberNode(tag, pendingProps, key, mode) { this.tag = tag; this.key = key; - this.sibling = this.child = this.return = this.stateNode = this.type = null; + this.stateNode = this.type = null; + this.sibling = this.child = this["return"] = null; this.index = 0; this.ref = null; this.pendingProps = pendingProps; @@ -1571,289 +1575,171 @@ function getStackAddendumByWorkInProgressFiber(workInProgress) { JSCompiler_inline_result = ""; } info += JSCompiler_inline_result; - workInProgress = workInProgress.return; + workInProgress = workInProgress["return"]; } while (workInProgress); return info; } new Set(); function createUpdateQueue(baseState) { return { - expirationTime: 0, baseState: baseState, - firstUpdate: null, - lastUpdate: null, - firstCapturedUpdate: null, - lastCapturedUpdate: null, - firstEffect: null, - lastEffect: null, - firstCapturedEffect: null, - lastCapturedEffect: null, - hasForceUpdate: !1 - }; -} -function cloneUpdateQueue(currentQueue) { - return { - expirationTime: currentQueue.expirationTime, - baseState: currentQueue.baseState, - firstUpdate: currentQueue.firstUpdate, - lastUpdate: currentQueue.lastUpdate, - firstCapturedUpdate: null, - lastCapturedUpdate: null, + expirationTime: 0, + first: null, + last: null, + callbackList: null, hasForceUpdate: !1, - firstEffect: null, - lastEffect: null, - firstCapturedEffect: null, - lastCapturedEffect: null + isInitialized: !1, + capturedValues: null }; } -function createUpdate(expirationTime) { - return { - expirationTime: expirationTime, - tag: 0, - payload: null, - callback: null, - next: null, - nextEffect: null - }; -} -function appendUpdateToQueue(queue, update, expirationTime) { - null === queue.lastUpdate - ? (queue.firstUpdate = queue.lastUpdate = update) - : ((queue.lastUpdate.next = update), (queue.lastUpdate = update)); - if (0 === queue.expirationTime || queue.expirationTime > expirationTime) - queue.expirationTime = expirationTime; -} -function enqueueUpdate(fiber, update, expirationTime) { - var alternate = fiber.alternate; - if (null === alternate) { - var queue1 = fiber.updateQueue; - var queue2 = null; - null === queue1 && - (queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState)); - } else - (queue1 = fiber.updateQueue), - (queue2 = alternate.updateQueue), - null === queue1 - ? null === queue2 - ? ((queue1 = fiber.updateQueue = createUpdateQueue( - fiber.memoizedState - )), - (queue2 = alternate.updateQueue = createUpdateQueue( - alternate.memoizedState - ))) - : (queue1 = fiber.updateQueue = cloneUpdateQueue(queue2)) - : null === queue2 && - (queue2 = alternate.updateQueue = cloneUpdateQueue(queue1)); - null === queue2 || queue1 === queue2 - ? appendUpdateToQueue(queue1, update, expirationTime) - : null === queue1.lastUpdate || null === queue2.lastUpdate - ? (appendUpdateToQueue(queue1, update, expirationTime), - appendUpdateToQueue(queue2, update, expirationTime)) - : (appendUpdateToQueue(queue1, update, expirationTime), - (queue2.lastUpdate = update)); -} -function enqueueCapturedUpdate(workInProgress, update, renderExpirationTime) { - var workInProgressQueue = workInProgress.updateQueue; - workInProgressQueue = - null === workInProgressQueue - ? (workInProgress.updateQueue = createUpdateQueue( - workInProgress.memoizedState - )) - : ensureWorkInProgressQueueIsAClone(workInProgress, workInProgressQueue); - null === workInProgressQueue.lastCapturedUpdate - ? (workInProgressQueue.firstCapturedUpdate = workInProgressQueue.lastCapturedUpdate = update) - : ((workInProgressQueue.lastCapturedUpdate.next = update), - (workInProgressQueue.lastCapturedUpdate = update)); +function insertUpdateIntoQueue(queue, update) { + null === queue.last + ? (queue.first = queue.last = update) + : ((queue.last.next = update), (queue.last = update)); if ( - 0 === workInProgressQueue.expirationTime || - workInProgressQueue.expirationTime > renderExpirationTime + 0 === queue.expirationTime || + queue.expirationTime > update.expirationTime ) - workInProgressQueue.expirationTime = renderExpirationTime; + queue.expirationTime = update.expirationTime; } -function ensureWorkInProgressQueueIsAClone(workInProgress, queue) { - var current = workInProgress.alternate; - null !== current && - queue === current.updateQueue && - (queue = workInProgress.updateQueue = cloneUpdateQueue(queue)); - return queue; +var q1 = void 0, + q2 = void 0; +function ensureUpdateQueues(fiber) { + q1 = q2 = null; + var alternateFiber = fiber.alternate, + queue1 = fiber.updateQueue; + null === queue1 && (queue1 = fiber.updateQueue = createUpdateQueue(null)); + null !== alternateFiber + ? ((fiber = alternateFiber.updateQueue), + null === fiber && + (fiber = alternateFiber.updateQueue = createUpdateQueue(null))) + : (fiber = null); + q1 = queue1; + q2 = fiber !== queue1 ? fiber : null; } -function getStateFromUpdate( - workInProgress, - queue, - update, - prevState, - nextProps, - instance -) { - switch (update.tag) { - case 1: - return ( - (workInProgress = update.payload), - "function" === typeof workInProgress - ? workInProgress.call(instance, prevState, nextProps) - : workInProgress - ); - case 3: - workInProgress.effectTag = (workInProgress.effectTag & -1025) | 64; - case 0: - workInProgress = update.payload; - nextProps = - "function" === typeof workInProgress - ? workInProgress.call(instance, prevState, nextProps) - : workInProgress; - if (null === nextProps || void 0 === nextProps) break; - return Object.assign({}, prevState, nextProps); - case 2: - queue.hasForceUpdate = !0; - } - return prevState; +function insertUpdateIntoFiber(fiber, update) { + ensureUpdateQueues(fiber); + fiber = q1; + var queue2 = q2; + null === queue2 + ? insertUpdateIntoQueue(fiber, update) + : null === fiber.last || null === queue2.last + ? (insertUpdateIntoQueue(fiber, update), + insertUpdateIntoQueue(queue2, update)) + : (insertUpdateIntoQueue(fiber, update), (queue2.last = update)); +} +function getStateFromUpdate(update, instance, prevState, props) { + update = update.partialState; + return "function" === typeof update + ? update.call(instance, prevState, props) + : update; } function processUpdateQueue( + current, workInProgress, queue, - props, instance, + props, renderExpirationTime ) { - if ( - !(0 === queue.expirationTime || queue.expirationTime > renderExpirationTime) + null !== current && + current.updateQueue === queue && + (queue = workInProgress.updateQueue = { + baseState: queue.baseState, + expirationTime: queue.expirationTime, + first: queue.first, + last: queue.last, + isInitialized: queue.isInitialized, + capturedValues: queue.capturedValues, + callbackList: null, + hasForceUpdate: !1 + }); + queue.expirationTime = 0; + queue.isInitialized + ? (current = queue.baseState) + : ((current = queue.baseState = workInProgress.memoizedState), + (queue.isInitialized = !0)); + for ( + var dontMutatePrevState = !0, update = queue.first, didSkip = !1; + null !== update; + ) { - queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue); + var updateExpirationTime = update.expirationTime; + if (updateExpirationTime > renderExpirationTime) { + var remainingExpirationTime = queue.expirationTime; + if ( + 0 === remainingExpirationTime || + remainingExpirationTime > updateExpirationTime + ) + queue.expirationTime = updateExpirationTime; + didSkip || ((didSkip = !0), (queue.baseState = current)); + } else { + didSkip || + ((queue.first = update.next), + null === queue.first && (queue.last = null)); + if (update.isReplace) + (current = getStateFromUpdate(update, instance, current, props)), + (dontMutatePrevState = !0); + else if ( + (updateExpirationTime = getStateFromUpdate( + update, + instance, + current, + props + )) + ) + (current = dontMutatePrevState + ? Object.assign({}, current, updateExpirationTime) + : Object.assign(current, updateExpirationTime)), + (dontMutatePrevState = !1); + update.isForced && (queue.hasForceUpdate = !0); + null !== update.callback && + ((updateExpirationTime = queue.callbackList), + null === updateExpirationTime && + (updateExpirationTime = queue.callbackList = []), + updateExpirationTime.push(update)); + null !== update.capturedValue && + ((updateExpirationTime = queue.capturedValues), + null === updateExpirationTime + ? (queue.capturedValues = [update.capturedValue]) + : updateExpirationTime.push(update.capturedValue)); + } + update = update.next; + } + null !== queue.callbackList + ? (workInProgress.effectTag |= 32) + : null !== queue.first || + queue.hasForceUpdate || + null !== queue.capturedValues || + (workInProgress.updateQueue = null); + didSkip || (queue.baseState = current); + return current; +} +function commitCallbacks(queue, context) { + var callbackList = queue.callbackList; + if (null !== callbackList) for ( - var newBaseState = queue.baseState, - newFirstUpdate = null, - newExpirationTime = 0, - update = queue.firstUpdate, - resultState = newBaseState; - null !== update; - + queue.callbackList = null, queue = 0; + queue < callbackList.length; + queue++ ) { - var updateExpirationTime = update.expirationTime; - if (updateExpirationTime > renderExpirationTime) { - if ( - (null === newFirstUpdate && - ((newFirstUpdate = update), (newBaseState = resultState)), - 0 === newExpirationTime || newExpirationTime > updateExpirationTime) - ) - newExpirationTime = updateExpirationTime; - } else - (resultState = getStateFromUpdate( - workInProgress, - queue, - update, - resultState, - props, - instance - )), - null !== update.callback && - ((workInProgress.effectTag |= 32), - (update.nextEffect = null), - null === queue.lastEffect - ? (queue.firstEffect = queue.lastEffect = update) - : ((queue.lastEffect.nextEffect = update), - (queue.lastEffect = update))); - update = update.next; + var update = callbackList[queue], + _callback = update.callback; + update.callback = null; + invariant( + "function" === typeof _callback, + "Invalid argument passed as callback. Expected a function. Instead received: %s", + _callback + ); + _callback.call(context); } - updateExpirationTime = null; - for (update = queue.firstCapturedUpdate; null !== update; ) { - var _updateExpirationTime = update.expirationTime; - if (_updateExpirationTime > renderExpirationTime) { - if ( - (null === updateExpirationTime && - ((updateExpirationTime = update), - null === newFirstUpdate && (newBaseState = resultState)), - 0 === newExpirationTime || newExpirationTime > _updateExpirationTime) - ) - newExpirationTime = _updateExpirationTime; - } else - (resultState = getStateFromUpdate( - workInProgress, - queue, - update, - resultState, - props, - instance - )), - null !== update.callback && - ((workInProgress.effectTag |= 32), - (update.nextEffect = null), - null === queue.lastCapturedEffect - ? (queue.firstCapturedEffect = queue.lastCapturedEffect = update) - : ((queue.lastCapturedEffect.nextEffect = update), - (queue.lastCapturedEffect = update))); - update = update.next; - } - null === newFirstUpdate && (queue.lastUpdate = null); - null === updateExpirationTime - ? (queue.lastCapturedUpdate = null) - : (workInProgress.effectTag |= 32); - null === newFirstUpdate && - null === updateExpirationTime && - (newBaseState = resultState); - queue.baseState = newBaseState; - queue.firstUpdate = newFirstUpdate; - queue.firstCapturedUpdate = updateExpirationTime; - queue.expirationTime = newExpirationTime; - workInProgress.memoizedState = resultState; - } -} -function callCallback(callback, context) { - invariant( - "function" === typeof callback, - "Invalid argument passed as callback. Expected a function. Instead received: %s", - callback - ); - callback.call(context); -} -function commitUpdateQueue(finishedWork, finishedQueue, instance) { - null !== finishedQueue.firstCapturedUpdate && - (null !== finishedQueue.lastUpdate && - ((finishedQueue.lastUpdate.next = finishedQueue.firstCapturedUpdate), - (finishedQueue.lastUpdate = finishedQueue.lastCapturedUpdate)), - (finishedQueue.firstCapturedUpdate = finishedQueue.lastCapturedUpdate = null)); - finishedWork = finishedQueue.firstEffect; - for ( - finishedQueue.firstEffect = finishedQueue.lastEffect = null; - null !== finishedWork; - - ) { - var _callback3 = finishedWork.callback; - null !== _callback3 && - ((finishedWork.callback = null), callCallback(_callback3, instance)); - finishedWork = finishedWork.nextEffect; - } - finishedWork = finishedQueue.firstCapturedEffect; - for ( - finishedQueue.firstCapturedEffect = finishedQueue.lastCapturedEffect = null; - null !== finishedWork; - - ) - (finishedQueue = finishedWork.callback), - null !== finishedQueue && - ((finishedWork.callback = null), callCallback(finishedQueue, instance)), - (finishedWork = finishedWork.nextEffect); -} -function applyDerivedStateFromProps( - workInProgress, - getDerivedStateFromProps, - nextProps -) { - var prevState = workInProgress.memoizedState; - getDerivedStateFromProps = getDerivedStateFromProps(nextProps, prevState); - prevState = - null === getDerivedStateFromProps || void 0 === getDerivedStateFromProps - ? prevState - : Object.assign({}, prevState, getDerivedStateFromProps); - workInProgress.memoizedState = prevState; - workInProgress = workInProgress.updateQueue; - null !== workInProgress && - 0 === workInProgress.expirationTime && - (workInProgress.baseState = prevState); } function ReactFiberClassComponent( legacyContext, scheduleWork, - computeExpirationForFiber + computeExpirationForFiber, + memoizeProps, + memoizeState ) { function checkShouldComponentUpdate( workInProgress, @@ -1864,8 +1750,9 @@ function ReactFiberClassComponent( newContext ) { if ( - null !== workInProgress.updateQueue && - workInProgress.updateQueue.hasForceUpdate + null === oldProps || + (null !== workInProgress.updateQueue && + workInProgress.updateQueue.hasForceUpdate) ) return !0; var instance = workInProgress.stateNode; @@ -1878,7 +1765,7 @@ function ReactFiberClassComponent( : !0; } function adoptClassInstance(workInProgress, instance) { - instance.updater = classComponentUpdater; + instance.updater = updater; workInProgress.stateNode = instance; instance._reactInternalFiber = workInProgress; } @@ -1894,52 +1781,78 @@ function ReactFiberClassComponent( "function" === typeof instance.UNSAFE_componentWillReceiveProps && instance.UNSAFE_componentWillReceiveProps(newProps, newContext); instance.state !== workInProgress && - classComponentUpdater.enqueueReplaceState(instance, instance.state, null); + updater.enqueueReplaceState(instance, instance.state, null); + } + function callGetDerivedStateFromProps( + workInProgress, + instance, + nextProps, + prevState + ) { + workInProgress = workInProgress.type; + if ("function" === typeof workInProgress.getDerivedStateFromProps) + return workInProgress.getDerivedStateFromProps.call( + null, + nextProps, + prevState + ); } var cacheContext = legacyContext.cacheContext, getMaskedContext = legacyContext.getMaskedContext, getUnmaskedContext = legacyContext.getUnmaskedContext, isContextConsumer = legacyContext.isContextConsumer, hasContextChanged = legacyContext.hasContextChanged, - classComponentUpdater = { + updater = { isMounted: isMounted, - enqueueSetState: function(inst, payload, callback) { - inst = inst._reactInternalFiber; - var expirationTime = computeExpirationForFiber(inst), - update = createUpdate(expirationTime); - update.payload = payload; - void 0 !== callback && - null !== callback && - (update.callback = callback); - enqueueUpdate(inst, update, expirationTime); - scheduleWork(inst, expirationTime); + enqueueSetState: function(instance, partialState, callback) { + instance = instance._reactInternalFiber; + callback = void 0 === callback ? null : callback; + var expirationTime = computeExpirationForFiber(instance); + insertUpdateIntoFiber(instance, { + expirationTime: expirationTime, + partialState: partialState, + callback: callback, + isReplace: !1, + isForced: !1, + capturedValue: null, + next: null + }); + scheduleWork(instance, expirationTime); }, - enqueueReplaceState: function(inst, payload, callback) { - inst = inst._reactInternalFiber; - var expirationTime = computeExpirationForFiber(inst), - update = createUpdate(expirationTime); - update.tag = 1; - update.payload = payload; - void 0 !== callback && - null !== callback && - (update.callback = callback); - enqueueUpdate(inst, update, expirationTime); - scheduleWork(inst, expirationTime); + enqueueReplaceState: function(instance, state, callback) { + instance = instance._reactInternalFiber; + callback = void 0 === callback ? null : callback; + var expirationTime = computeExpirationForFiber(instance); + insertUpdateIntoFiber(instance, { + expirationTime: expirationTime, + partialState: state, + callback: callback, + isReplace: !0, + isForced: !1, + capturedValue: null, + next: null + }); + scheduleWork(instance, expirationTime); }, - enqueueForceUpdate: function(inst, callback) { - inst = inst._reactInternalFiber; - var expirationTime = computeExpirationForFiber(inst), - update = createUpdate(expirationTime); - update.tag = 2; - void 0 !== callback && - null !== callback && - (update.callback = callback); - enqueueUpdate(inst, update, expirationTime); - scheduleWork(inst, expirationTime); + enqueueForceUpdate: function(instance, callback) { + instance = instance._reactInternalFiber; + callback = void 0 === callback ? null : callback; + var expirationTime = computeExpirationForFiber(instance); + insertUpdateIntoFiber(instance, { + expirationTime: expirationTime, + partialState: null, + callback: callback, + isReplace: !1, + isForced: !0, + capturedValue: null, + next: null + }); + scheduleWork(instance, expirationTime); } }; return { adoptClassInstance: adoptClassInstance, + callGetDerivedStateFromProps: callGetDerivedStateFromProps, constructClassInstance: function(workInProgress, props) { var ctor = workInProgress.type, unmaskedContext = getUnmaskedContext(workInProgress), @@ -1947,15 +1860,25 @@ function ReactFiberClassComponent( context = needsContext ? getMaskedContext(workInProgress, unmaskedContext) : emptyObject; - props = new ctor(props, context); - workInProgress.memoizedState = - null !== props.state && void 0 !== props.state ? props.state : null; - adoptClassInstance(workInProgress, props); + ctor = new ctor(props, context); + var state = + null !== ctor.state && void 0 !== ctor.state ? ctor.state : null; + adoptClassInstance(workInProgress, ctor); + workInProgress.memoizedState = state; + props = callGetDerivedStateFromProps(workInProgress, ctor, props, state); + null !== props && + void 0 !== props && + (workInProgress.memoizedState = Object.assign( + {}, + workInProgress.memoizedState, + props + )); needsContext && cacheContext(workInProgress, unmaskedContext, context); - return props; + return ctor; }, mountClassInstance: function(workInProgress, renderExpirationTime) { var ctor = workInProgress.type, + current = workInProgress.alternate, instance = workInProgress.stateNode, props = workInProgress.pendingProps, unmaskedContext = getUnmaskedContext(workInProgress); @@ -1963,20 +1886,6 @@ function ReactFiberClassComponent( instance.state = workInProgress.memoizedState; instance.refs = emptyObject; instance.context = getMaskedContext(workInProgress, unmaskedContext); - unmaskedContext = workInProgress.updateQueue; - null !== unmaskedContext && - (processUpdateQueue( - workInProgress, - unmaskedContext, - props, - instance, - renderExpirationTime - ), - (instance.state = workInProgress.memoizedState)); - unmaskedContext = workInProgress.type.getDerivedStateFromProps; - "function" === typeof unmaskedContext && - (applyDerivedStateFromProps(workInProgress, unmaskedContext, props), - (instance.state = workInProgress.memoizedState)); "function" === typeof ctor.getDerivedStateFromProps || "function" === typeof instance.getSnapshotBeforeUpdate || ("function" !== typeof instance.UNSAFE_componentWillMount && @@ -1987,36 +1896,32 @@ function ReactFiberClassComponent( "function" === typeof instance.UNSAFE_componentWillMount && instance.UNSAFE_componentWillMount(), ctor !== instance.state && - classComponentUpdater.enqueueReplaceState( - instance, - instance.state, - null - ), - (unmaskedContext = workInProgress.updateQueue), - null !== unmaskedContext && - (processUpdateQueue( + updater.enqueueReplaceState(instance, instance.state, null), + (ctor = workInProgress.updateQueue), + null !== ctor && + (instance.state = processUpdateQueue( + current, workInProgress, - unmaskedContext, - props, + ctor, instance, + props, renderExpirationTime - ), - (instance.state = workInProgress.memoizedState))); + ))); "function" === typeof instance.componentDidMount && (workInProgress.effectTag |= 4); }, resumeMountClassInstance: function(workInProgress, renderExpirationTime) { var ctor = workInProgress.type, - instance = workInProgress.stateNode, - oldProps = workInProgress.memoizedProps, - newProps = workInProgress.pendingProps; - instance.props = oldProps; - var oldContext = instance.context, + instance = workInProgress.stateNode; + instance.props = workInProgress.memoizedProps; + instance.state = workInProgress.memoizedState; + var oldProps = workInProgress.memoizedProps, + newProps = workInProgress.pendingProps, + oldContext = instance.context, newUnmaskedContext = getUnmaskedContext(workInProgress); newUnmaskedContext = getMaskedContext(workInProgress, newUnmaskedContext); - var getDerivedStateFromProps = ctor.getDerivedStateFromProps; (ctor = - "function" === typeof getDerivedStateFromProps || + "function" === typeof ctor.getDerivedStateFromProps || "function" === typeof instance.getSnapshotBeforeUpdate) || ("function" !== typeof instance.UNSAFE_componentWillReceiveProps && "function" !== typeof instance.componentWillReceiveProps) || @@ -2027,29 +1932,43 @@ function ReactFiberClassComponent( newProps, newUnmaskedContext )); - var oldState = workInProgress.memoizedState; - oldContext = instance.state = oldState; - var updateQueue = workInProgress.updateQueue; - null !== updateQueue && - (processUpdateQueue( + oldContext = workInProgress.memoizedState; + renderExpirationTime = + null !== workInProgress.updateQueue + ? processUpdateQueue( + null, + workInProgress, + workInProgress.updateQueue, + instance, + newProps, + renderExpirationTime + ) + : oldContext; + var derivedStateFromProps = void 0; + oldProps !== newProps && + (derivedStateFromProps = callGetDerivedStateFromProps( workInProgress, - updateQueue, - newProps, instance, + newProps, renderExpirationTime - ), - (oldContext = workInProgress.memoizedState)); - "function" === typeof getDerivedStateFromProps && - (applyDerivedStateFromProps( - workInProgress, - getDerivedStateFromProps, - newProps - ), - (oldContext = workInProgress.memoizedState)); + )); + if (null !== derivedStateFromProps && void 0 !== derivedStateFromProps) { + renderExpirationTime = + null === renderExpirationTime || void 0 === renderExpirationTime + ? derivedStateFromProps + : Object.assign({}, renderExpirationTime, derivedStateFromProps); + var _updateQueue = workInProgress.updateQueue; + null !== _updateQueue && + (_updateQueue.baseState = Object.assign( + {}, + _updateQueue.baseState, + derivedStateFromProps + )); + } if ( !( oldProps !== newProps || - oldState !== oldContext || + oldContext !== renderExpirationTime || hasContextChanged() || (null !== workInProgress.updateQueue && workInProgress.updateQueue.hasForceUpdate) @@ -2060,12 +1979,12 @@ function ReactFiberClassComponent( (workInProgress.effectTag |= 4), !1 ); - (renderExpirationTime = checkShouldComponentUpdate( + (oldProps = checkShouldComponentUpdate( workInProgress, oldProps, newProps, - oldState, oldContext, + renderExpirationTime, newUnmaskedContext )) ? (ctor || @@ -2079,12 +1998,12 @@ function ReactFiberClassComponent( (workInProgress.effectTag |= 4)) : ("function" === typeof instance.componentDidMount && (workInProgress.effectTag |= 4), - (workInProgress.memoizedProps = newProps), - (workInProgress.memoizedState = oldContext)); + memoizeProps(workInProgress, newProps), + memoizeState(workInProgress, renderExpirationTime)); instance.props = newProps; - instance.state = oldContext; + instance.state = renderExpirationTime; instance.context = newUnmaskedContext; - return renderExpirationTime; + return oldProps; }, updateClassInstance: function( current, @@ -2092,16 +2011,16 @@ function ReactFiberClassComponent( renderExpirationTime ) { var ctor = workInProgress.type, - instance = workInProgress.stateNode, - oldProps = workInProgress.memoizedProps, - newProps = workInProgress.pendingProps; - instance.props = oldProps; - var oldContext = instance.context, + instance = workInProgress.stateNode; + instance.props = workInProgress.memoizedProps; + instance.state = workInProgress.memoizedState; + var oldProps = workInProgress.memoizedProps, + newProps = workInProgress.pendingProps, + oldContext = instance.context, newUnmaskedContext = getUnmaskedContext(workInProgress); newUnmaskedContext = getMaskedContext(workInProgress, newUnmaskedContext); - var getDerivedStateFromProps = ctor.getDerivedStateFromProps; (ctor = - "function" === typeof getDerivedStateFromProps || + "function" === typeof ctor.getDerivedStateFromProps || "function" === typeof instance.getSnapshotBeforeUpdate) || ("function" !== typeof instance.UNSAFE_componentWillReceiveProps && "function" !== typeof instance.componentWillReceiveProps) || @@ -2113,28 +2032,42 @@ function ReactFiberClassComponent( newUnmaskedContext )); oldContext = workInProgress.memoizedState; - var newState = (instance.state = oldContext), - updateQueue = workInProgress.updateQueue; - null !== updateQueue && - (processUpdateQueue( + renderExpirationTime = + null !== workInProgress.updateQueue + ? processUpdateQueue( + current, + workInProgress, + workInProgress.updateQueue, + instance, + newProps, + renderExpirationTime + ) + : oldContext; + var derivedStateFromProps = void 0; + oldProps !== newProps && + (derivedStateFromProps = callGetDerivedStateFromProps( workInProgress, - updateQueue, - newProps, instance, + newProps, renderExpirationTime - ), - (newState = workInProgress.memoizedState)); - "function" === typeof getDerivedStateFromProps && - (applyDerivedStateFromProps( - workInProgress, - getDerivedStateFromProps, - newProps - ), - (newState = workInProgress.memoizedState)); + )); + if (null !== derivedStateFromProps && void 0 !== derivedStateFromProps) { + renderExpirationTime = + null === renderExpirationTime || void 0 === renderExpirationTime + ? derivedStateFromProps + : Object.assign({}, renderExpirationTime, derivedStateFromProps); + var _updateQueue3 = workInProgress.updateQueue; + null !== _updateQueue3 && + (_updateQueue3.baseState = Object.assign( + {}, + _updateQueue3.baseState, + derivedStateFromProps + )); + } if ( !( oldProps !== newProps || - oldContext !== newState || + oldContext !== renderExpirationTime || hasContextChanged() || (null !== workInProgress.updateQueue && workInProgress.updateQueue.hasForceUpdate) @@ -2148,15 +2081,15 @@ function ReactFiberClassComponent( "function" !== typeof instance.getSnapshotBeforeUpdate || (oldProps === current.memoizedProps && oldContext === current.memoizedState) || - (workInProgress.effectTag |= 256), + (workInProgress.effectTag |= 2048), !1 ); - (renderExpirationTime = checkShouldComponentUpdate( + (derivedStateFromProps = checkShouldComponentUpdate( workInProgress, oldProps, newProps, oldContext, - newState, + renderExpirationTime, newUnmaskedContext )) ? (ctor || @@ -2165,19 +2098,19 @@ function ReactFiberClassComponent( ("function" === typeof instance.componentWillUpdate && instance.componentWillUpdate( newProps, - newState, + renderExpirationTime, newUnmaskedContext ), "function" === typeof instance.UNSAFE_componentWillUpdate && instance.UNSAFE_componentWillUpdate( newProps, - newState, + renderExpirationTime, newUnmaskedContext )), "function" === typeof instance.componentDidUpdate && (workInProgress.effectTag |= 4), "function" === typeof instance.getSnapshotBeforeUpdate && - (workInProgress.effectTag |= 256)) + (workInProgress.effectTag |= 2048)) : ("function" !== typeof instance.componentDidUpdate || (oldProps === current.memoizedProps && oldContext === current.memoizedState) || @@ -2185,13 +2118,13 @@ function ReactFiberClassComponent( "function" !== typeof instance.getSnapshotBeforeUpdate || (oldProps === current.memoizedProps && oldContext === current.memoizedState) || - (workInProgress.effectTag |= 256), - (workInProgress.memoizedProps = newProps), - (workInProgress.memoizedState = newState)); + (workInProgress.effectTag |= 2048), + memoizeProps(workInProgress, newProps), + memoizeState(workInProgress, renderExpirationTime)); instance.props = newProps; - instance.state = newState; + instance.state = renderExpirationTime; instance.context = newUnmaskedContext; - return renderExpirationTime; + return derivedStateFromProps; } }; } @@ -2315,11 +2248,11 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime )), - (current.return = returnFiber), + (current["return"] = returnFiber), current ); current = useFiber(current, textContent, expirationTime); - current.return = returnFiber; + current["return"] = returnFiber; return current; } function updateElement(returnFiber, current, element, expirationTime) { @@ -2327,7 +2260,7 @@ function ChildReconciler(shouldTrackSideEffects) { return ( (expirationTime = useFiber(current, element.props, expirationTime)), (expirationTime.ref = coerceRef(returnFiber, current, element)), - (expirationTime.return = returnFiber), + (expirationTime["return"] = returnFiber), expirationTime ); expirationTime = createFiberFromElement( @@ -2336,7 +2269,7 @@ function ChildReconciler(shouldTrackSideEffects) { expirationTime ); expirationTime.ref = coerceRef(returnFiber, current, element); - expirationTime.return = returnFiber; + expirationTime["return"] = returnFiber; return expirationTime; } function updatePortal(returnFiber, current, portal, expirationTime) { @@ -2352,11 +2285,11 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime )), - (current.return = returnFiber), + (current["return"] = returnFiber), current ); current = useFiber(current, portal.children || [], expirationTime); - current.return = returnFiber; + current["return"] = returnFiber; return current; } function updateFragment(returnFiber, current, fragment, expirationTime, key) { @@ -2368,11 +2301,11 @@ function ChildReconciler(shouldTrackSideEffects) { expirationTime, key )), - (current.return = returnFiber), + (current["return"] = returnFiber), current ); current = useFiber(current, fragment, expirationTime); - current.return = returnFiber; + current["return"] = returnFiber; return current; } function createChild(returnFiber, newChild, expirationTime) { @@ -2383,7 +2316,7 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime )), - (newChild.return = returnFiber), + (newChild["return"] = returnFiber), newChild ); if ("object" === typeof newChild && null !== newChild) { @@ -2396,7 +2329,7 @@ function ChildReconciler(shouldTrackSideEffects) { expirationTime )), (expirationTime.ref = coerceRef(returnFiber, null, newChild)), - (expirationTime.return = returnFiber), + (expirationTime["return"] = returnFiber), expirationTime ); case REACT_PORTAL_TYPE: @@ -2406,7 +2339,7 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime )), - (newChild.return = returnFiber), + (newChild["return"] = returnFiber), newChild ); } @@ -2418,7 +2351,7 @@ function ChildReconciler(shouldTrackSideEffects) { expirationTime, null )), - (newChild.return = returnFiber), + (newChild["return"] = returnFiber), newChild ); throwOnInvalidObjectType(returnFiber, newChild); @@ -2605,21 +2538,17 @@ function ChildReconciler(shouldTrackSideEffects) { newChildren[newIdx], expirationTime )) - ) - shouldTrackSideEffects && - null !== nextOldFiber.alternate && - oldFiber.delete( + ) { + if (shouldTrackSideEffects && null !== nextOldFiber.alternate) + oldFiber["delete"]( null === nextOldFiber.key ? newIdx : nextOldFiber.key - ), - (currentFirstChild = placeChild( - nextOldFiber, - currentFirstChild, - newIdx - )), - null === previousNewFiber - ? (resultingFirstChild = nextOldFiber) - : (previousNewFiber.sibling = nextOldFiber), - (previousNewFiber = nextOldFiber); + ); + currentFirstChild = placeChild(nextOldFiber, currentFirstChild, newIdx); + null === previousNewFiber + ? (resultingFirstChild = nextOldFiber) + : (previousNewFiber.sibling = nextOldFiber); + previousNewFiber = nextOldFiber; + } shouldTrackSideEffects && oldFiber.forEach(function(child) { return deleteChild(returnFiber, child); @@ -2693,22 +2622,24 @@ function ChildReconciler(shouldTrackSideEffects) { !step.done; newIdx++, step = newChildrenIterable.next() ) - (step = updateFromMap( - oldFiber, - returnFiber, - newIdx, - step.value, - expirationTime - )), - null !== step && - (shouldTrackSideEffects && - null !== step.alternate && - oldFiber.delete(null === step.key ? newIdx : step.key), - (currentFirstChild = placeChild(step, currentFirstChild, newIdx)), - null === previousNewFiber - ? (iteratorFn = step) - : (previousNewFiber.sibling = step), - (previousNewFiber = step)); + if ( + ((step = updateFromMap( + oldFiber, + returnFiber, + newIdx, + step.value, + expirationTime + )), + null !== step) + ) { + if (shouldTrackSideEffects && null !== step.alternate) + oldFiber["delete"](null === step.key ? newIdx : step.key); + currentFirstChild = placeChild(step, currentFirstChild, newIdx); + null === previousNewFiber + ? (iteratorFn = step) + : (previousNewFiber.sibling = step); + previousNewFiber = step; + } shouldTrackSideEffects && oldFiber.forEach(function(child) { return deleteChild(returnFiber, child); @@ -2747,7 +2678,7 @@ function ChildReconciler(shouldTrackSideEffects) { isObject, newChild ); - currentFirstChild.return = returnFiber; + currentFirstChild["return"] = returnFiber; returnFiber = currentFirstChild; break a; } else { @@ -2764,7 +2695,7 @@ function ChildReconciler(shouldTrackSideEffects) { expirationTime, newChild.key )), - (currentFirstChild.return = returnFiber), + (currentFirstChild["return"] = returnFiber), (returnFiber = currentFirstChild)) : ((expirationTime = createFiberFromElement( newChild, @@ -2776,7 +2707,7 @@ function ChildReconciler(shouldTrackSideEffects) { currentFirstChild, newChild )), - (expirationTime.return = returnFiber), + (expirationTime["return"] = returnFiber), (returnFiber = expirationTime)); } return placeSingleChild(returnFiber); @@ -2800,7 +2731,7 @@ function ChildReconciler(shouldTrackSideEffects) { newChild.children || [], expirationTime ); - currentFirstChild.return = returnFiber; + currentFirstChild["return"] = returnFiber; returnFiber = currentFirstChild; break a; } else { @@ -2815,7 +2746,7 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime ); - currentFirstChild.return = returnFiber; + currentFirstChild["return"] = returnFiber; returnFiber = currentFirstChild; } return placeSingleChild(returnFiber); @@ -2830,7 +2761,7 @@ function ChildReconciler(shouldTrackSideEffects) { newChild, expirationTime )), - (currentFirstChild.return = returnFiber), + (currentFirstChild["return"] = returnFiber), (returnFiber = currentFirstChild)) : (deleteRemainingChildren(returnFiber, currentFirstChild), (currentFirstChild = createFiberFromText( @@ -2838,7 +2769,7 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime )), - (currentFirstChild.return = returnFiber), + (currentFirstChild["return"] = returnFiber), (returnFiber = currentFirstChild)), placeSingleChild(returnFiber) ); @@ -2924,10 +2855,10 @@ function ReactFiberBeginWork( workInProgress, shouldUpdate, hasContext, + didCaptureError, renderExpirationTime ) { markRef(current, workInProgress); - var didCaptureError = 0 !== (workInProgress.effectTag & 64); if (!shouldUpdate && !didCaptureError) return ( hasContext && invalidateContextProvider(workInProgress, !1), @@ -2975,8 +2906,11 @@ function ReactFiberBeginWork( renderExpirationTime ) { var fiber = workInProgress.child; - null !== fiber && (fiber.return = workInProgress); - for (; null !== fiber; ) { + for ( + null !== fiber && (fiber["return"] = workInProgress); + null !== fiber; + + ) { switch (fiber.tag) { case 12: var nextFiber = fiber.stateNode | 0; @@ -2999,7 +2933,7 @@ function ReactFiberBeginWork( ) alternate.expirationTime = renderExpirationTime; else break; - nextFiber = nextFiber.return; + nextFiber = nextFiber["return"]; } nextFiber = null; } else nextFiber = fiber.child; @@ -3010,7 +2944,7 @@ function ReactFiberBeginWork( default: nextFiber = fiber.child; } - if (null !== nextFiber) nextFiber.return = fiber; + if (null !== nextFiber) nextFiber["return"] = fiber; else for (nextFiber = fiber; null !== nextFiber; ) { if (nextFiber === workInProgress) { @@ -3019,11 +2953,10 @@ function ReactFiberBeginWork( } fiber = nextFiber.sibling; if (null !== fiber) { - fiber.return = nextFiber.return; nextFiber = fiber; break; } - nextFiber = nextFiber.return; + nextFiber = nextFiber["return"]; } fiber = nextFiber; } @@ -3035,10 +2968,8 @@ function ReactFiberBeginWork( ) { var context = workInProgress.type._context, newProps = workInProgress.pendingProps, - oldProps = workInProgress.memoizedProps, - canBailOnProps = !0; - if (hasLegacyContextChanged()) canBailOnProps = !1; - else if (oldProps === newProps) + oldProps = workInProgress.memoizedProps; + if (!hasLegacyContextChanged() && oldProps === newProps) return ( (workInProgress.stateNode = 0), pushProvider(workInProgress), @@ -3048,7 +2979,7 @@ function ReactFiberBeginWork( workInProgress.memoizedProps = newProps; if (null === oldProps) newValue = 1073741823; else if (oldProps.value === newProps.value) { - if (oldProps.children === newProps.children && canBailOnProps) + if (oldProps.children === newProps.children) return ( (workInProgress.stateNode = 0), pushProvider(workInProgress), @@ -3062,7 +2993,7 @@ function ReactFiberBeginWork( (0 !== oldValue || 1 / oldValue === 1 / newValue)) || (oldValue !== oldValue && newValue !== newValue) ) { - if (oldProps.children === newProps.children && canBailOnProps) + if (oldProps.children === newProps.children) return ( (workInProgress.stateNode = 0), pushProvider(workInProgress), @@ -3077,7 +3008,7 @@ function ReactFiberBeginWork( (newValue |= 0), 0 === newValue) ) { - if (oldProps.children === newProps.children && canBailOnProps) + if (oldProps.children === newProps.children) return ( (workInProgress.stateNode = 0), pushProvider(workInProgress), @@ -3109,14 +3040,14 @@ function ReactFiberBeginWork( current.expirationTime ); workInProgress.child = newChild; - for (newChild.return = workInProgress; null !== current.sibling; ) + for (newChild["return"] = workInProgress; null !== current.sibling; ) (current = current.sibling), (newChild = newChild.sibling = createWorkInProgress( current, current.pendingProps, current.expirationTime )), - (newChild.return = workInProgress); + (newChild["return"] = workInProgress); newChild.sibling = null; } return workInProgress.child; @@ -3148,6 +3079,7 @@ function ReactFiberBeginWork( } ); var adoptClassInstance = config.adoptClassInstance, + callGetDerivedStateFromProps = config.callGetDerivedStateFromProps, constructClassInstance = config.constructClassInstance, mountClassInstance = config.mountClassInstance, resumeMountClassInstance = config.resumeMountClassInstance, @@ -3196,13 +3128,20 @@ function ReactFiberBeginWork( (workInProgress.tag = 2), (workInProgress.memoizedState = null !== fn.state && void 0 !== fn.state ? fn.state : null), - (unmaskedContext = unmaskedContext.getDerivedStateFromProps), - "function" === typeof unmaskedContext && - applyDerivedStateFromProps( + "function" === typeof unmaskedContext.getDerivedStateFromProps && + ((props = callGetDerivedStateFromProps( workInProgress, - unmaskedContext, - props - ), + fn, + props, + workInProgress.memoizedState + )), + null !== props && + void 0 !== props && + (workInProgress.memoizedState = Object.assign( + {}, + workInProgress.memoizedState, + props + ))), (props = pushLegacyContextProvider(workInProgress)), adoptClassInstance(workInProgress, fn), mountClassInstance(workInProgress, renderExpirationTime), @@ -3211,6 +3150,7 @@ function ReactFiberBeginWork( workInProgress, !0, props, + !1, renderExpirationTime ))) : ((workInProgress.tag = 1), @@ -3238,100 +3178,103 @@ function ReactFiberBeginWork( current ); case 2: - return ( - (props = pushLegacyContextProvider(workInProgress)), - null === current - ? null === workInProgress.stateNode - ? (constructClassInstance( - workInProgress, - workInProgress.pendingProps, - renderExpirationTime - ), - mountClassInstance(workInProgress, renderExpirationTime), - (fn = !0)) - : (fn = resumeMountClassInstance( - workInProgress, - renderExpirationTime - )) - : (fn = updateClassInstance( - current, + props = pushLegacyContextProvider(workInProgress); + null === current + ? null === workInProgress.stateNode + ? (constructClassInstance( + workInProgress, + workInProgress.pendingProps + ), + mountClassInstance(workInProgress, renderExpirationTime), + (fn = !0)) + : (fn = resumeMountClassInstance( workInProgress, renderExpirationTime - )), - finishClassComponent( + )) + : (fn = updateClassInstance( + current, + workInProgress, + renderExpirationTime + )); + unmaskedContext = !1; + var updateQueue = workInProgress.updateQueue; + null !== updateQueue && + null !== updateQueue.capturedValues && + (unmaskedContext = fn = !0); + return finishClassComponent( + current, + workInProgress, + fn, + props, + unmaskedContext, + renderExpirationTime + ); + case 3: + a: if ( + (pushHostRootContext(workInProgress), + (fn = workInProgress.updateQueue), + null !== fn) + ) { + unmaskedContext = workInProgress.memoizedState; + props = processUpdateQueue( current, workInProgress, fn, - props, + null, + null, renderExpirationTime - ) - ); - case 3: - return ( - pushHostRootContext(workInProgress), - (props = workInProgress.updateQueue), - null !== props - ? ((fn = workInProgress.memoizedState), - (fn = null !== fn ? fn.element : null), - processUpdateQueue( + ); + workInProgress.memoizedState = props; + fn = workInProgress.updateQueue; + if (null !== fn && null !== fn.capturedValues) fn = null; + else if (unmaskedContext === props) { + resetHydrationState(); + current = bailoutOnAlreadyFinishedWork(current, workInProgress); + break a; + } else fn = props.element; + unmaskedContext = workInProgress.stateNode; + (null === current || null === current.child) && + unmaskedContext.hydrate && + enterHydrationState(workInProgress) + ? ((workInProgress.effectTag |= 2), + (workInProgress.child = mountChildFibers( workInProgress, - props, - workInProgress.pendingProps, null, + fn, renderExpirationTime - ), - (props = workInProgress.memoizedState.element), - props === fn - ? (resetHydrationState(), - (current = bailoutOnAlreadyFinishedWork( - current, - workInProgress - ))) - : ((fn = workInProgress.stateNode), - (null === current || null === current.child) && - fn.hydrate && - enterHydrationState(workInProgress) - ? ((workInProgress.effectTag |= 2), - (workInProgress.child = mountChildFibers( - workInProgress, - null, - props, - renderExpirationTime - ))) - : (resetHydrationState(), - reconcileChildren(current, workInProgress, props)), - (current = workInProgress.child))) + ))) : (resetHydrationState(), - (current = bailoutOnAlreadyFinishedWork( - current, - workInProgress - ))), - current - ); + reconcileChildren(current, workInProgress, fn)); + workInProgress.memoizedState = props; + current = workInProgress.child; + } else + resetHydrationState(), + (current = bailoutOnAlreadyFinishedWork(current, workInProgress)); + return current; case 5: a: { pushHostContext(workInProgress); null === current && tryToClaimNextHydratableInstance(workInProgress); props = workInProgress.type; - var memoizedProps = workInProgress.memoizedProps; + updateQueue = workInProgress.memoizedProps; fn = workInProgress.pendingProps; unmaskedContext = null !== current ? current.memoizedProps : null; - if (!hasLegacyContextChanged() && memoizedProps === fn) { + if (!hasLegacyContextChanged() && updateQueue === fn) { if ( - (memoizedProps = + (updateQueue = workInProgress.mode & 1 && shouldDeprioritizeSubtree(props, fn)) ) workInProgress.expirationTime = 1073741823; - if (!memoizedProps || 1073741823 !== renderExpirationTime) { + if (!updateQueue || 1073741823 !== renderExpirationTime) { current = bailoutOnAlreadyFinishedWork(current, workInProgress); break a; } } - memoizedProps = fn.children; + updateQueue = fn.children; shouldSetTextContent(props, fn) - ? (memoizedProps = null) + ? (updateQueue = null) : unmaskedContext && shouldSetTextContent(props, unmaskedContext) && (workInProgress.effectTag |= 16); @@ -3342,7 +3285,7 @@ function ReactFiberBeginWork( ? ((workInProgress.expirationTime = 1073741823), (workInProgress.memoizedProps = fn), (current = null)) - : (reconcileChildren(current, workInProgress, memoizedProps), + : (reconcileChildren(current, workInProgress, updateQueue), (workInProgress.memoizedProps = fn), (current = workInProgress.child)); } @@ -3408,21 +3351,14 @@ function ReactFiberBeginWork( ); case 14: return ( - (props = workInProgress.type.render), - (renderExpirationTime = workInProgress.pendingProps), - (fn = workInProgress.ref), - hasLegacyContextChanged() || - workInProgress.memoizedProps !== renderExpirationTime || - fn !== (null !== current ? current.ref : null) - ? ((props = props(renderExpirationTime, fn)), - reconcileChildren(current, workInProgress, props), - (workInProgress.memoizedProps = renderExpirationTime), - (current = workInProgress.child)) - : (current = bailoutOnAlreadyFinishedWork( - current, - workInProgress - )), - current + (renderExpirationTime = workInProgress.type.render), + (renderExpirationTime = renderExpirationTime( + workInProgress.pendingProps, + workInProgress.ref + )), + reconcileChildren(current, workInProgress, renderExpirationTime), + (workInProgress.memoizedProps = renderExpirationTime), + workInProgress.child ); case 10: return ( @@ -3471,13 +3407,13 @@ function ReactFiberBeginWork( a: { fn = workInProgress.type; unmaskedContext = workInProgress.pendingProps; - memoizedProps = workInProgress.memoizedProps; + updateQueue = workInProgress.memoizedProps; props = fn._currentValue; var changedBits = fn._changedBits; if ( hasLegacyContextChanged() || 0 !== changedBits || - memoizedProps !== unmaskedContext + updateQueue !== unmaskedContext ) { workInProgress.memoizedProps = unmaskedContext; var observedBits = unmaskedContext.unstable_observedBits; @@ -3491,13 +3427,12 @@ function ReactFiberBeginWork( changedBits, renderExpirationTime ); - else if (memoizedProps === unmaskedContext) { + else if (updateQueue === unmaskedContext) { current = bailoutOnAlreadyFinishedWork(current, workInProgress); break a; } renderExpirationTime = unmaskedContext.children; renderExpirationTime = renderExpirationTime(props); - workInProgress.effectTag |= 1; reconcileChildren(current, workInProgress, renderExpirationTime); current = workInProgress.child; } else @@ -3528,16 +3463,17 @@ function ReactFiberCompleteWork( if (5 === node.tag || 6 === node.tag) appendInitialChild(parent, node.stateNode); else if (4 !== node.tag && null !== node.child) { - node.child.return = node; + node.child["return"] = node; node = node.child; continue; } if (node === workInProgress) break; for (; null === node.sibling; ) { - if (null === node.return || node.return === workInProgress) return; - node = node.return; + if (null === node["return"] || node["return"] === workInProgress) + return; + node = node["return"]; } - node.sibling.return = node.return; + node.sibling["return"] = node["return"]; node = node.sibling; } } @@ -3578,16 +3514,17 @@ function ReactFiberCompleteWork( if (5 === node.tag || 6 === node.tag) appendChildToContainerChildSet(newChildSet, node.stateNode); else if (4 !== node.tag && null !== node.child) { - node.child.return = node; + node.child["return"] = node; node = node.child; continue; } if (node === workInProgress) break a; for (; null === node.sibling; ) { - if (null === node.return || node.return === workInProgress) break a; - node = node.return; + if (null === node["return"] || node["return"] === workInProgress) + break a; + node = node["return"]; } - node.sibling.return = node.return; + node.sibling["return"] = node["return"]; node = node.sibling; } portalOrRoot.pendingChildren = newChildSet; @@ -3651,7 +3588,18 @@ function ReactFiberCompleteWork( case 1: return null; case 2: - return popLegacyContextProvider(workInProgress), null; + return ( + popLegacyContextProvider(workInProgress), + (current = workInProgress.stateNode), + (newProps = workInProgress.updateQueue), + null !== newProps && + null !== newProps.capturedValues && + ((workInProgress.effectTag &= -65), + "function" === typeof current.componentDidCatch + ? (workInProgress.effectTag |= 256) + : (newProps.capturedValues = null)), + null + ); case 3: popHostContainer(workInProgress); popTopLevelLegacyContextObject(workInProgress); @@ -3662,6 +3610,10 @@ function ReactFiberCompleteWork( if (null === current || null === current.child) popHydrationState(workInProgress), (workInProgress.effectTag &= -3); updateHostContainer(workInProgress); + current = workInProgress.updateQueue; + null !== current && + null !== current.capturedValues && + (workInProgress.effectTag |= 256); return null; case 5: popHostContext(workInProgress); @@ -3669,10 +3621,10 @@ function ReactFiberCompleteWork( var type = workInProgress.type; if (null !== current && null != workInProgress.stateNode) { var oldProps = current.memoizedProps, - instance = workInProgress.stateNode, + _instance = workInProgress.stateNode, currentHostContext = getHostContext(); - instance = prepareUpdate( - instance, + _instance = prepareUpdate( + _instance, type, oldProps, newProps, @@ -3682,7 +3634,7 @@ function ReactFiberCompleteWork( updateHostComponent( current, workInProgress, - instance, + _instance, type, oldProps, newProps, @@ -3764,34 +3716,30 @@ function ReactFiberCompleteWork( ); workInProgress.tag = 8; type = []; - a: { - if ((oldProps = workInProgress.stateNode)) - oldProps.return = workInProgress; - for (; null !== oldProps; ) { - if ( - 5 === oldProps.tag || - 6 === oldProps.tag || - 4 === oldProps.tag - ) - invariant(!1, "A call cannot have host component children."); - else if (9 === oldProps.tag) - type.push(oldProps.pendingProps.value); - else if (null !== oldProps.child) { - oldProps.child.return = oldProps; - oldProps = oldProps.child; - continue; - } - for (; null === oldProps.sibling; ) { - if ( - null === oldProps.return || - oldProps.return === workInProgress - ) - break a; - oldProps = oldProps.return; - } - oldProps.sibling.return = oldProps.return; - oldProps = oldProps.sibling; + a: for ( + (oldProps = workInProgress.stateNode) && + (oldProps["return"] = workInProgress); + null !== oldProps; + + ) { + if (5 === oldProps.tag || 6 === oldProps.tag || 4 === oldProps.tag) + invariant(!1, "A call cannot have host component children."); + else if (9 === oldProps.tag) type.push(oldProps.pendingProps.value); + else if (null !== oldProps.child) { + oldProps.child["return"] = oldProps; + oldProps = oldProps.child; + continue; } + for (; null === oldProps.sibling; ) { + if ( + null === oldProps["return"] || + oldProps["return"] === workInProgress + ) + break a; + oldProps = oldProps["return"]; + } + oldProps.sibling["return"] = oldProps["return"]; + oldProps = oldProps.sibling; } oldProps = newProps.handler; newProps = oldProps(newProps.props, type); @@ -3836,351 +3784,53 @@ function ReactFiberCompleteWork( } }; } -function createCapturedValue(value, source) { - return { - value: value, - source: source, - stack: getStackAddendumByWorkInProgressFiber(source) - }; -} -function logError(boundary, errorInfo) { - var source = errorInfo.source; - null === errorInfo.stack && getStackAddendumByWorkInProgressFiber(source); - null !== source && getComponentName(source); - errorInfo = errorInfo.value; - null !== boundary && 2 === boundary.tag && getComponentName(boundary); - try { - (errorInfo && errorInfo.suppressReactErrorLogging) || - console.error(errorInfo); - } catch (e) { - (e && e.suppressReactErrorLogging) || console.error(e); - } -} -function ReactFiberCommitWork(config, captureError) { - function safelyDetachRef(current) { - var ref = current.ref; - if (null !== ref) - if ("function" === typeof ref) - try { - ref(null); - } catch (refError) { - captureError(current, refError); - } - else ref.current = null; - } - function commitBeforeMutationLifeCycles(current, finishedWork) { - switch (finishedWork.tag) { - case 2: - if (finishedWork.effectTag & 256 && null !== current) { - var prevProps = current.memoizedProps, - prevState = current.memoizedState; - current = finishedWork.stateNode; - current.props = finishedWork.memoizedProps; - current.state = finishedWork.memoizedState; - finishedWork = current.getSnapshotBeforeUpdate(prevProps, prevState); - current.__reactInternalSnapshotBeforeUpdate = finishedWork; - } - break; - case 3: - case 5: - case 6: - case 4: - break; - default: - invariant( - !1, - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); - } - } - function commitLifeCycles( - finishedRoot, - current, - finishedWork, - currentTime, - committedExpirationTime - ) { - switch (finishedWork.tag) { - case 2: - finishedRoot = finishedWork.stateNode; - finishedWork.effectTag & 4 && - (null === current - ? ((finishedRoot.props = finishedWork.memoizedProps), - (finishedRoot.state = finishedWork.memoizedState), - finishedRoot.componentDidMount()) - : ((currentTime = current.memoizedProps), - (current = current.memoizedState), - (finishedRoot.props = finishedWork.memoizedProps), - (finishedRoot.state = finishedWork.memoizedState), - finishedRoot.componentDidUpdate( - currentTime, - current, - finishedRoot.__reactInternalSnapshotBeforeUpdate - ))); - current = finishedWork.updateQueue; - null !== current && - ((finishedRoot.props = finishedWork.memoizedProps), - (finishedRoot.state = finishedWork.memoizedState), - commitUpdateQueue( - finishedWork, - current, - finishedRoot, - committedExpirationTime - )); - break; - case 3: - current = finishedWork.updateQueue; - if (null !== current) { - finishedRoot = null; - if (null !== finishedWork.child) - switch (finishedWork.child.tag) { - case 5: - finishedRoot = getPublicInstance(finishedWork.child.stateNode); - break; - case 2: - finishedRoot = finishedWork.child.stateNode; - } - commitUpdateQueue( - finishedWork, - current, - finishedRoot, - committedExpirationTime - ); - } - break; - case 5: - committedExpirationTime = finishedWork.stateNode; - null === current && - finishedWork.effectTag & 4 && - commitMount( - committedExpirationTime, - finishedWork.type, - finishedWork.memoizedProps, - finishedWork - ); - break; - case 6: - break; - case 4: - break; - default: - invariant( - !1, - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); - } - } - function commitAttachRef(finishedWork) { - var ref = finishedWork.ref; - if (null !== ref) { - var _instance5 = finishedWork.stateNode; - switch (finishedWork.tag) { - case 5: - finishedWork = getPublicInstance(_instance5); - break; - default: - finishedWork = _instance5; - } - "function" === typeof ref - ? ref(finishedWork) - : (ref.current = finishedWork); - } - } - function commitDetachRef(current) { - current = current.ref; - null !== current && - ("function" === typeof current - ? current(null) - : (current.current = null)); - } - function commitNestedUnmounts(root) { - for (var node = root; ; ) { - var current = node; - "function" === typeof onCommitUnmount && onCommitUnmount(current); - switch (current.tag) { - case 2: - safelyDetachRef(current); - var _instance6 = current.stateNode; - if ("function" === typeof _instance6.componentWillUnmount) - try { - (_instance6.props = current.memoizedProps), - (_instance6.state = current.memoizedState), - _instance6.componentWillUnmount(); - } catch (unmountError) { - captureError(current, unmountError); - } - break; - case 5: - safelyDetachRef(current); - break; - case 7: - commitNestedUnmounts(current.stateNode); - break; - case 4: - persistence && emptyPortalContainer(current); - } - if (null === node.child || (mutation && 4 === node.tag)) { - if (node === root) break; - for (; null === node.sibling; ) { - if (null === node.return || node.return === root) return; - node = node.return; - } - node.sibling.return = node.return; - node = node.sibling; - } else (node.child.return = node), (node = node.child); - } - } - var getPublicInstance = config.getPublicInstance, - mutation = config.mutation, - persistence = config.persistence, - emptyPortalContainer = void 0; - if (!mutation) { - var commitContainer = void 0; - if (persistence) { - var replaceContainerChildren = persistence.replaceContainerChildren, - createContainerChildSet = persistence.createContainerChildSet; - emptyPortalContainer = function(current) { - current = current.stateNode.containerInfo; - var emptyChildSet = createContainerChildSet(current); - replaceContainerChildren(current, emptyChildSet); - }; - commitContainer = function(finishedWork) { - switch (finishedWork.tag) { - case 2: - break; - case 5: - break; - case 6: - break; - case 3: - case 4: - finishedWork = finishedWork.stateNode; - replaceContainerChildren( - finishedWork.containerInfo, - finishedWork.pendingChildren - ); - break; - default: - invariant( - !1, - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); - } - }; - } else commitContainer = function() {}; - return { - commitResetTextContent: function() {}, - commitPlacement: function() {}, - commitDeletion: function(current) { - commitNestedUnmounts(current); - current.return = null; - current.child = null; - current.alternate && - ((current.alternate.child = null), (current.alternate.return = null)); - }, - commitWork: function(current, finishedWork) { - commitContainer(finishedWork); - }, - commitLifeCycles: commitLifeCycles, - commitBeforeMutationLifeCycles: commitBeforeMutationLifeCycles, - commitAttachRef: commitAttachRef, - commitDetachRef: commitDetachRef - }; - } - var commitMount = mutation.commitMount; - invariant(!1, "Mutating reconciler is disabled."); -} function ReactFiberUnwindWork( hostContext, legacyContext, newContext, scheduleWork, - markLegacyErrorBoundaryAsFailed, - isAlreadyFailedLegacyErrorBoundary, - onUncaughtError + isAlreadyFailedLegacyErrorBoundary ) { - function createRootErrorUpdate(fiber, errorInfo, expirationTime) { - expirationTime = createUpdate(expirationTime); - expirationTime.tag = 3; - expirationTime.payload = { element: null }; - var error = errorInfo.value; - expirationTime.callback = function() { - onUncaughtError(error); - logError(fiber, errorInfo); - }; - return expirationTime; - } - function createClassErrorUpdate(fiber, errorInfo, expirationTime) { - expirationTime = createUpdate(expirationTime); - expirationTime.tag = 3; - var inst = fiber.stateNode; - null !== inst && - "function" === typeof inst.componentDidCatch && - (expirationTime.callback = function() { - markLegacyErrorBoundaryAsFailed(this); - var error = errorInfo.value, - stack = errorInfo.stack; - logError(fiber, errorInfo); - this.componentDidCatch(error, { - componentStack: null !== stack ? stack : "" - }); - }); - return expirationTime; - } var popHostContainer = hostContext.popHostContainer, popHostContext = hostContext.popHostContext, popLegacyContextProvider = legacyContext.popContextProvider, popTopLevelLegacyContextObject = legacyContext.popTopLevelContextObject, popProvider = newContext.popProvider; return { - throwException: function( - returnFiber, - sourceFiber, - rawValue, - renderExpirationTime - ) { + throwException: function(returnFiber, sourceFiber, rawValue) { sourceFiber.effectTag |= 512; sourceFiber.firstEffect = sourceFiber.lastEffect = null; - sourceFiber = createCapturedValue(rawValue, sourceFiber); + sourceFiber = { + value: rawValue, + source: sourceFiber, + stack: getStackAddendumByWorkInProgressFiber(sourceFiber) + }; do { switch (returnFiber.tag) { case 3: + ensureUpdateQueues(returnFiber); + returnFiber.updateQueue.capturedValues = [sourceFiber]; returnFiber.effectTag |= 1024; - sourceFiber = createRootErrorUpdate( - returnFiber, - sourceFiber, - renderExpirationTime - ); - enqueueCapturedUpdate( - returnFiber, - sourceFiber, - renderExpirationTime - ); return; case 2: - rawValue = sourceFiber; - var _instance = returnFiber.stateNode; if ( + ((rawValue = returnFiber.stateNode), 0 === (returnFiber.effectTag & 64) && - null !== _instance && - "function" === typeof _instance.componentDidCatch && - !isAlreadyFailedLegacyErrorBoundary(_instance) + null !== rawValue && + "function" === typeof rawValue.componentDidCatch && + !isAlreadyFailedLegacyErrorBoundary(rawValue)) ) { + ensureUpdateQueues(returnFiber); + rawValue = returnFiber.updateQueue; + var capturedValues = rawValue.capturedValues; + null === capturedValues + ? (rawValue.capturedValues = [sourceFiber]) + : capturedValues.push(sourceFiber); returnFiber.effectTag |= 1024; - sourceFiber = createClassErrorUpdate( - returnFiber, - rawValue, - renderExpirationTime - ); - enqueueCapturedUpdate( - returnFiber, - sourceFiber, - renderExpirationTime - ); return; } } - returnFiber = returnFiber.return; + returnFiber = returnFiber["return"]; } while (null !== returnFiber); }, unwindWork: function(workInProgress) { @@ -4230,11 +3880,293 @@ function ReactFiberUnwindWork( case 13: popProvider(interruptedWork); } - }, - createRootErrorUpdate: createRootErrorUpdate, - createClassErrorUpdate: createClassErrorUpdate + } }; } +function logError(boundary, errorInfo) { + var source = errorInfo.source; + null === errorInfo.stack && getStackAddendumByWorkInProgressFiber(source); + null !== source && getComponentName(source); + errorInfo = errorInfo.value; + null !== boundary && 2 === boundary.tag && getComponentName(boundary); + try { + (errorInfo && errorInfo.suppressReactErrorLogging) || + console.error(errorInfo); + } catch (e) { + (e && e.suppressReactErrorLogging) || console.error(e); + } +} +function ReactFiberCommitWork( + config, + captureError, + scheduleWork, + computeExpirationForFiber, + markLegacyErrorBoundaryAsFailed +) { + function safelyDetachRef(current) { + var ref = current.ref; + if (null !== ref) + if ("function" === typeof ref) + try { + ref(null); + } catch (refError) { + captureError(current, refError); + } + else ref.current = null; + } + function commitBeforeMutationLifeCycles(current, finishedWork) { + switch (finishedWork.tag) { + case 2: + if (finishedWork.effectTag & 2048 && null !== current) { + var prevProps = current.memoizedProps, + prevState = current.memoizedState; + current = finishedWork.stateNode; + current.props = finishedWork.memoizedProps; + current.state = finishedWork.memoizedState; + finishedWork = current.getSnapshotBeforeUpdate(prevProps, prevState); + current.__reactInternalSnapshotBeforeUpdate = finishedWork; + } + break; + case 3: + case 5: + case 6: + case 4: + break; + default: + invariant( + !1, + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); + } + } + function commitLifeCycles(finishedRoot, current, finishedWork) { + switch (finishedWork.tag) { + case 2: + finishedRoot = finishedWork.stateNode; + if (finishedWork.effectTag & 4) + if (null === current) + (finishedRoot.props = finishedWork.memoizedProps), + (finishedRoot.state = finishedWork.memoizedState), + finishedRoot.componentDidMount(); + else { + var prevProps = current.memoizedProps; + current = current.memoizedState; + finishedRoot.props = finishedWork.memoizedProps; + finishedRoot.state = finishedWork.memoizedState; + finishedRoot.componentDidUpdate( + prevProps, + current, + finishedRoot.__reactInternalSnapshotBeforeUpdate + ); + } + finishedWork = finishedWork.updateQueue; + null !== finishedWork && commitCallbacks(finishedWork, finishedRoot); + break; + case 3: + current = finishedWork.updateQueue; + if (null !== current) { + finishedRoot = null; + if (null !== finishedWork.child) + switch (finishedWork.child.tag) { + case 5: + finishedRoot = getPublicInstance(finishedWork.child.stateNode); + break; + case 2: + finishedRoot = finishedWork.child.stateNode; + } + commitCallbacks(current, finishedRoot); + } + break; + case 5: + finishedRoot = finishedWork.stateNode; + null === current && + finishedWork.effectTag & 4 && + commitMount( + finishedRoot, + finishedWork.type, + finishedWork.memoizedProps, + finishedWork + ); + break; + case 6: + break; + case 4: + break; + default: + invariant( + !1, + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); + } + } + function commitErrorLogging(finishedWork, onUncaughtError) { + switch (finishedWork.tag) { + case 2: + var ctor = finishedWork.type; + onUncaughtError = finishedWork.stateNode; + var updateQueue = finishedWork.updateQueue; + invariant( + null !== updateQueue && null !== updateQueue.capturedValues, + "An error logging effect should not have been scheduled if no errors were captured. This error is likely caused by a bug in React. Please file an issue." + ); + var capturedErrors = updateQueue.capturedValues; + updateQueue.capturedValues = null; + "function" !== typeof ctor.getDerivedStateFromCatch && + markLegacyErrorBoundaryAsFailed(onUncaughtError); + onUncaughtError.props = finishedWork.memoizedProps; + onUncaughtError.state = finishedWork.memoizedState; + for (ctor = 0; ctor < capturedErrors.length; ctor++) { + updateQueue = capturedErrors[ctor]; + var _error = updateQueue.value, + stack = updateQueue.stack; + logError(finishedWork, updateQueue); + onUncaughtError.componentDidCatch(_error, { + componentStack: null !== stack ? stack : "" + }); + } + break; + case 3: + ctor = finishedWork.updateQueue; + invariant( + null !== ctor && null !== ctor.capturedValues, + "An error logging effect should not have been scheduled if no errors were captured. This error is likely caused by a bug in React. Please file an issue." + ); + capturedErrors = ctor.capturedValues; + ctor.capturedValues = null; + for (ctor = 0; ctor < capturedErrors.length; ctor++) + (updateQueue = capturedErrors[ctor]), + logError(finishedWork, updateQueue), + onUncaughtError(updateQueue.value); + break; + default: + invariant( + !1, + "This unit of work tag cannot capture errors. This error is likely caused by a bug in React. Please file an issue." + ); + } + } + function commitAttachRef(finishedWork) { + var ref = finishedWork.ref; + if (null !== ref) { + var _instance6 = finishedWork.stateNode; + switch (finishedWork.tag) { + case 5: + finishedWork = getPublicInstance(_instance6); + break; + default: + finishedWork = _instance6; + } + "function" === typeof ref + ? ref(finishedWork) + : (ref.current = finishedWork); + } + } + function commitDetachRef(current) { + current = current.ref; + null !== current && + ("function" === typeof current + ? current(null) + : (current.current = null)); + } + function commitNestedUnmounts(root) { + for (var node = root; ; ) { + var current = node; + "function" === typeof onCommitUnmount && onCommitUnmount(current); + switch (current.tag) { + case 2: + safelyDetachRef(current); + var _instance7 = current.stateNode; + if ("function" === typeof _instance7.componentWillUnmount) + try { + (_instance7.props = current.memoizedProps), + (_instance7.state = current.memoizedState), + _instance7.componentWillUnmount(); + } catch (unmountError) { + captureError(current, unmountError); + } + break; + case 5: + safelyDetachRef(current); + break; + case 7: + commitNestedUnmounts(current.stateNode); + break; + case 4: + persistence && emptyPortalContainer(current); + } + if (null === node.child || (mutation && 4 === node.tag)) { + if (node === root) break; + for (; null === node.sibling; ) { + if (null === node["return"] || node["return"] === root) return; + node = node["return"]; + } + node.sibling["return"] = node["return"]; + node = node.sibling; + } else (node.child["return"] = node), (node = node.child); + } + } + var getPublicInstance = config.getPublicInstance, + mutation = config.mutation, + persistence = config.persistence, + emptyPortalContainer = void 0; + if (!mutation) { + var commitContainer = void 0; + if (persistence) { + var replaceContainerChildren = persistence.replaceContainerChildren, + createContainerChildSet = persistence.createContainerChildSet; + emptyPortalContainer = function(current) { + current = current.stateNode.containerInfo; + var emptyChildSet = createContainerChildSet(current); + replaceContainerChildren(current, emptyChildSet); + }; + commitContainer = function(finishedWork) { + switch (finishedWork.tag) { + case 2: + break; + case 5: + break; + case 6: + break; + case 3: + case 4: + finishedWork = finishedWork.stateNode; + replaceContainerChildren( + finishedWork.containerInfo, + finishedWork.pendingChildren + ); + break; + default: + invariant( + !1, + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); + } + }; + } else commitContainer = function() {}; + return { + commitResetTextContent: function() {}, + commitPlacement: function() {}, + commitDeletion: function(current) { + commitNestedUnmounts(current); + current["return"] = null; + current.child = null; + current.alternate && + ((current.alternate.child = null), + (current.alternate["return"] = null)); + }, + commitWork: function(current, finishedWork) { + commitContainer(finishedWork); + }, + commitLifeCycles: commitLifeCycles, + commitBeforeMutationLifeCycles: commitBeforeMutationLifeCycles, + commitErrorLogging: commitErrorLogging, + commitAttachRef: commitAttachRef, + commitDetachRef: commitDetachRef + }; + } + var commitMount = mutation.commitMount; + invariant(!1, "Mutating reconciler is disabled."); +} var NO_CONTEXT = {}; function ReactFiberHostContext(config, stack) { function requiredContext(c) { @@ -4291,7 +4223,7 @@ function ReactFiberHydrationContext(config) { var fiber = new FiberNode(5, null, null, 0); fiber.type = "DELETED"; fiber.stateNode = instance; - fiber.return = returnFiber; + fiber["return"] = returnFiber; fiber.effectTag = 8; null !== returnFiber.lastEffect ? ((returnFiber.lastEffect.nextEffect = fiber), @@ -4323,11 +4255,11 @@ function ReactFiberHydrationContext(config) { } function popToNextHostParent(fiber) { for ( - fiber = fiber.return; + fiber = fiber["return"]; null !== fiber && 5 !== fiber.tag && 3 !== fiber.tag; ) - fiber = fiber.return; + fiber = fiber["return"]; hydrationParentFiber = fiber; } var shouldSetTextContent = config.shouldSetTextContent; @@ -4561,7 +4493,7 @@ function ReactFiberLegacyContext(stack) { ) { if (isContextProvider(fiber)) return fiber.stateNode.__reactInternalMemoizedMergedChildContext; - fiber = fiber.return; + fiber = fiber["return"]; invariant( fiber, "Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue." @@ -4628,12 +4560,12 @@ function ReactFiberScheduler(config) { function resetStack() { if (null !== nextUnitOfWork) for ( - var interruptedWork = nextUnitOfWork.return; + var interruptedWork = nextUnitOfWork["return"]; null !== interruptedWork; ) unwindInterruptedWork(interruptedWork), - (interruptedWork = interruptedWork.return); + (interruptedWork = interruptedWork["return"]); nextRoot = null; nextRenderExpirationTime = 0; nextUnitOfWork = null; @@ -4645,71 +4577,74 @@ function ReactFiberScheduler(config) { legacyErrorBoundariesThatAlreadyFailed.has(instance) ); } - function markLegacyErrorBoundaryAsFailed(instance) { - null === legacyErrorBoundariesThatAlreadyFailed - ? (legacyErrorBoundariesThatAlreadyFailed = new Set([instance])) - : legacyErrorBoundariesThatAlreadyFailed.add(instance); - } - function completeUnitOfWork(workInProgress) { + function completeUnitOfWork(workInProgress$jscomp$0) { for (;;) { - var current = workInProgress.alternate, - returnFiber = workInProgress.return, - siblingFiber = workInProgress.sibling; - if (0 === (workInProgress.effectTag & 512)) { + var current = workInProgress$jscomp$0.alternate, + returnFiber = workInProgress$jscomp$0["return"], + siblingFiber = workInProgress$jscomp$0.sibling; + if (0 === (workInProgress$jscomp$0.effectTag & 512)) { current = completeWork( current, - workInProgress, + workInProgress$jscomp$0, nextRenderExpirationTime ); + var workInProgress = workInProgress$jscomp$0; if ( 1073741823 === nextRenderExpirationTime || 1073741823 !== workInProgress.expirationTime ) { - var newExpirationTime = 0; - switch (workInProgress.tag) { + b: switch (workInProgress.tag) { case 3: case 2: - var updateQueue = workInProgress.updateQueue; - null !== updateQueue && - (newExpirationTime = updateQueue.expirationTime); + var newExpirationTime = workInProgress.updateQueue; + newExpirationTime = + null === newExpirationTime + ? 0 + : newExpirationTime.expirationTime; + break b; + default: + newExpirationTime = 0; } - for (updateQueue = workInProgress.child; null !== updateQueue; ) - 0 !== updateQueue.expirationTime && + for (var child = workInProgress.child; null !== child; ) + 0 !== child.expirationTime && (0 === newExpirationTime || - newExpirationTime > updateQueue.expirationTime) && - (newExpirationTime = updateQueue.expirationTime), - (updateQueue = updateQueue.sibling); + newExpirationTime > child.expirationTime) && + (newExpirationTime = child.expirationTime), + (child = child.sibling); workInProgress.expirationTime = newExpirationTime; } if (null !== current) return current; null !== returnFiber && 0 === (returnFiber.effectTag & 512) && (null === returnFiber.firstEffect && - (returnFiber.firstEffect = workInProgress.firstEffect), - null !== workInProgress.lastEffect && + (returnFiber.firstEffect = workInProgress$jscomp$0.firstEffect), + null !== workInProgress$jscomp$0.lastEffect && (null !== returnFiber.lastEffect && - (returnFiber.lastEffect.nextEffect = workInProgress.firstEffect), - (returnFiber.lastEffect = workInProgress.lastEffect)), - 1 < workInProgress.effectTag && + (returnFiber.lastEffect.nextEffect = + workInProgress$jscomp$0.firstEffect), + (returnFiber.lastEffect = workInProgress$jscomp$0.lastEffect)), + 1 < workInProgress$jscomp$0.effectTag && (null !== returnFiber.lastEffect - ? (returnFiber.lastEffect.nextEffect = workInProgress) - : (returnFiber.firstEffect = workInProgress), - (returnFiber.lastEffect = workInProgress))); + ? (returnFiber.lastEffect.nextEffect = workInProgress$jscomp$0) + : (returnFiber.firstEffect = workInProgress$jscomp$0), + (returnFiber.lastEffect = workInProgress$jscomp$0))); if (null !== siblingFiber) return siblingFiber; - if (null !== returnFiber) workInProgress = returnFiber; + if (null !== returnFiber) workInProgress$jscomp$0 = returnFiber; else { isRootReadyForCommit = !0; break; } } else { - workInProgress = unwindWork(workInProgress); - if (null !== workInProgress) - return (workInProgress.effectTag &= 511), workInProgress; + workInProgress$jscomp$0 = unwindWork(workInProgress$jscomp$0); + if (null !== workInProgress$jscomp$0) + return ( + (workInProgress$jscomp$0.effectTag &= 2559), workInProgress$jscomp$0 + ); null !== returnFiber && ((returnFiber.firstEffect = returnFiber.lastEffect = null), (returnFiber.effectTag |= 512)); if (null !== siblingFiber) return siblingFiber; - if (null !== returnFiber) workInProgress = returnFiber; + if (null !== returnFiber) workInProgress$jscomp$0 = returnFiber; else break; } } @@ -4761,18 +4696,13 @@ function ReactFiberScheduler(config) { break; } isAsync = nextUnitOfWork; - var returnFiber = isAsync.return; + var returnFiber = isAsync["return"]; if (null === returnFiber) { didFatal = !0; onUncaughtError(thrownValue); break; } - throwException( - returnFiber, - isAsync, - thrownValue, - nextRenderExpirationTime - ); + throwException(returnFiber, isAsync, thrownValue); nextUnitOfWork = completeUnitOfWork(isAsync); } break; @@ -4789,61 +4719,55 @@ function ReactFiberScheduler(config) { "Expired work should have completed. This error is likely caused by a bug in React. Please file an issue." ); } - function onCommitPhaseError(fiber, error) { - var JSCompiler_inline_result; + function scheduleCapture(sourceFiber, boundaryFiber, value, expirationTime) { + sourceFiber = { + value: value, + source: sourceFiber, + stack: getStackAddendumByWorkInProgressFiber(sourceFiber) + }; + insertUpdateIntoFiber(boundaryFiber, { + expirationTime: expirationTime, + partialState: null, + callback: null, + isReplace: !1, + isForced: !1, + capturedValue: sourceFiber, + next: null + }); + scheduleWork(boundaryFiber, expirationTime); + } + function onCommitPhaseError(fiber$jscomp$0, error) { a: { invariant( !isWorking || isCommitting, "dispatch: Cannot dispatch during the render phase." ); - for ( - JSCompiler_inline_result = fiber.return; - null !== JSCompiler_inline_result; - - ) { - switch (JSCompiler_inline_result.tag) { + for (var fiber = fiber$jscomp$0["return"]; null !== fiber; ) { + switch (fiber.tag) { case 2: - var instance = JSCompiler_inline_result.stateNode; + var instance = fiber.stateNode; if ( - "function" === - typeof JSCompiler_inline_result.type.getDerivedStateFromCatch || + "function" === typeof fiber.type.getDerivedStateFromCatch || ("function" === typeof instance.componentDidCatch && !isAlreadyFailedLegacyErrorBoundary(instance)) ) { - fiber = createCapturedValue(error, fiber); - fiber = createClassErrorUpdate( - JSCompiler_inline_result, - fiber, - 1 - ); - enqueueUpdate(JSCompiler_inline_result, fiber, 1); - scheduleWork(JSCompiler_inline_result, 1); - JSCompiler_inline_result = void 0; + scheduleCapture(fiber$jscomp$0, fiber, error, 1); + fiber$jscomp$0 = void 0; break a; } break; case 3: - fiber = createCapturedValue(error, fiber); - fiber = createRootErrorUpdate(JSCompiler_inline_result, fiber, 1); - enqueueUpdate(JSCompiler_inline_result, fiber, 1); - scheduleWork(JSCompiler_inline_result, 1); - JSCompiler_inline_result = void 0; + scheduleCapture(fiber$jscomp$0, fiber, error, 1); + fiber$jscomp$0 = void 0; break a; } - JSCompiler_inline_result = JSCompiler_inline_result.return; + fiber = fiber["return"]; } - 3 === fiber.tag && - ((JSCompiler_inline_result = createCapturedValue(error, fiber)), - (JSCompiler_inline_result = createRootErrorUpdate( - fiber, - JSCompiler_inline_result, - 1 - )), - enqueueUpdate(fiber, JSCompiler_inline_result, 1), - scheduleWork(fiber, 1)); - JSCompiler_inline_result = void 0; + 3 === fiber$jscomp$0.tag && + scheduleCapture(fiber$jscomp$0, fiber$jscomp$0, error, 1); + fiber$jscomp$0 = void 0; } - return JSCompiler_inline_result; + return fiber$jscomp$0; } function computeExpirationForFiber(fiber) { fiber = @@ -4871,7 +4795,7 @@ function ReactFiberScheduler(config) { (0 === fiber.alternate.expirationTime || fiber.alternate.expirationTime > expirationTime) && (fiber.alternate.expirationTime = expirationTime); - if (null === fiber.return) + if (null === fiber["return"]) if (3 === fiber.tag) { var root = fiber.stateNode; !isWorking && @@ -4889,7 +4813,7 @@ function ReactFiberScheduler(config) { expirationTime = void 0; break a; } - fiber = fiber.return; + fiber = fiber["return"]; } expirationTime = void 0; } @@ -5129,7 +5053,7 @@ function ReactFiberScheduler(config) { error = void 0; try { for (; null !== nextEffect; ) - nextEffect.effectTag & 256 && + nextEffect.effectTag & 2048 && commitBeforeMutationLifeCycles(nextEffect.alternate, nextEffect), (nextEffect = nextEffect.nextEffect); } catch (e) { @@ -5205,6 +5129,8 @@ function ReactFiberScheduler(config) { didError, error ); + effectTag$jscomp$0 & 256 && + commitErrorLogging(nextEffect, onUncaughtError); effectTag$jscomp$0 & 128 && commitAttachRef(nextEffect); var next = nextEffect.nextEffect; nextEffect.nextEffect = null; @@ -5267,21 +5193,21 @@ function ReactFiberScheduler(config) { legacyContext, stack, scheduleWork, - markLegacyErrorBoundaryAsFailed, - isAlreadyFailedLegacyErrorBoundary, - onUncaughtError + isAlreadyFailedLegacyErrorBoundary ); var throwException = hostContext.throwException, unwindWork = hostContext.unwindWork, - unwindInterruptedWork = hostContext.unwindInterruptedWork, - createRootErrorUpdate = hostContext.createRootErrorUpdate, - createClassErrorUpdate = hostContext.createClassErrorUpdate; + unwindInterruptedWork = hostContext.unwindInterruptedWork; hostContext = ReactFiberCommitWork( config, onCommitPhaseError, scheduleWork, computeExpirationForFiber, - markLegacyErrorBoundaryAsFailed, + function(instance) { + null === legacyErrorBoundariesThatAlreadyFailed + ? (legacyErrorBoundariesThatAlreadyFailed = new Set([instance])) + : legacyErrorBoundariesThatAlreadyFailed.add(instance); + }, recalculateCurrentTime ); var commitBeforeMutationLifeCycles = @@ -5291,6 +5217,7 @@ function ReactFiberScheduler(config) { commitDeletion = hostContext.commitDeletion, commitWork = hostContext.commitWork, commitLifeCycles = hostContext.commitLifeCycles, + commitErrorLogging = hostContext.commitErrorLogging, commitAttachRef = hostContext.commitAttachRef, commitDetachRef = hostContext.commitDetachRef, now = config.now, @@ -5458,11 +5385,15 @@ function ReactFiberReconciler$1(config) { ? (container.context = parentComponent) : (container.pendingContext = parentComponent); container = callback; - callback = createUpdate(expirationTime); - callback.payload = { element: element }; - container = void 0 === container ? null : container; - null !== container && (callback.callback = container); - enqueueUpdate(currentTime, callback, expirationTime); + insertUpdateIntoFiber(currentTime, { + expirationTime: expirationTime, + partialState: { element: element }, + callback: void 0 === container ? null : container, + isReplace: !1, + isForced: !1, + capturedValue: null, + next: null + }); scheduleWork(currentTime, expirationTime); return expirationTime; } @@ -5583,8 +5514,8 @@ var ReactFiberReconciler$2 = Object.freeze({ default: ReactFiberReconciler$1 }), ReactFiberReconciler$3 = (ReactFiberReconciler$2 && ReactFiberReconciler$1) || ReactFiberReconciler$2, - reactReconciler = ReactFiberReconciler$3.default - ? ReactFiberReconciler$3.default + reactReconciler = ReactFiberReconciler$3["default"] + ? ReactFiberReconciler$3["default"] : ReactFiberReconciler$3, nextReactTag = 2, ReactFabricHostComponent = (function() { @@ -5864,7 +5795,7 @@ var roots = new Map(), var root = roots.get(containerTag); root && ReactFabricRenderer.updateContainer(null, root, null, function() { - roots.delete(containerTag); + roots["delete"](containerTag); }); }, createPortal: function(children, containerTag) { @@ -5939,4 +5870,6 @@ ReactFabricRenderer.injectIntoDevTools({ }); var ReactFabric$2 = Object.freeze({ default: ReactFabric }), ReactFabric$3 = (ReactFabric$2 && ReactFabric) || ReactFabric$2; -module.exports = ReactFabric$3.default ? ReactFabric$3.default : ReactFabric$3; +module.exports = ReactFabric$3["default"] + ? ReactFabric$3["default"] + : ReactFabric$3; diff --git a/Libraries/Renderer/oss/ReactNativeRenderer-dev.js b/Libraries/Renderer/oss/ReactNativeRenderer-dev.js index 6c6430d3eff..21d9a6c1d54 100644 --- a/Libraries/Renderer/oss/ReactNativeRenderer-dev.js +++ b/Libraries/Renderer/oss/ReactNativeRenderer-dev.js @@ -5,7 +5,6 @@ * LICENSE file in the root directory of this source tree. * * @noflow - * @providesModule ReactNativeRenderer-dev * @preventMunge */ @@ -27,9 +26,9 @@ var deepDiffer = require("deepDiffer"); var flattenStyle = require("flattenStyle"); var React = require("react"); var emptyObject = require("fbjs/lib/emptyObject"); -var checkPropTypes = require("prop-types/checkPropTypes"); var shallowEqual = require("fbjs/lib/shallowEqual"); var ExceptionsManager = require("ExceptionsManager"); +var checkPropTypes = require("prop-types/checkPropTypes"); var deepFreezeAndThrowOnMutationInDev = require("deepFreezeAndThrowOnMutationInDev"); var invokeGuardedCallback = function(name, func, context, a, b, c, d, e, f) { @@ -971,7 +970,7 @@ var ForwardRef = 14; function getParent(inst) { do { - inst = inst.return; + inst = inst["return"]; // TODO: If this is a HostRoot we might want to bail out. // That is depending on if we want nested subtrees (layers) to bubble // events to their parent. We could also go through parentNode on the @@ -2717,21 +2716,23 @@ RCTEventEmitter.register(ReactNativeEventEmitter); // The Symbol used to tag the ReactElement-like types. If there is no native Symbol // nor polyfill, then a plain number is used for performance. -var hasSymbol = typeof Symbol === "function" && Symbol.for; +var hasSymbol = typeof Symbol === "function" && Symbol["for"]; -var REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for("react.element") : 0xeac7; -var REACT_CALL_TYPE = hasSymbol ? Symbol.for("react.call") : 0xeac8; -var REACT_RETURN_TYPE = hasSymbol ? Symbol.for("react.return") : 0xeac9; -var REACT_PORTAL_TYPE = hasSymbol ? Symbol.for("react.portal") : 0xeaca; -var REACT_FRAGMENT_TYPE = hasSymbol ? Symbol.for("react.fragment") : 0xeacb; +var REACT_ELEMENT_TYPE = hasSymbol ? Symbol["for"]("react.element") : 0xeac7; +var REACT_CALL_TYPE = hasSymbol ? Symbol["for"]("react.call") : 0xeac8; +var REACT_RETURN_TYPE = hasSymbol ? Symbol["for"]("react.return") : 0xeac9; +var REACT_PORTAL_TYPE = hasSymbol ? Symbol["for"]("react.portal") : 0xeaca; +var REACT_FRAGMENT_TYPE = hasSymbol ? Symbol["for"]("react.fragment") : 0xeacb; var REACT_STRICT_MODE_TYPE = hasSymbol - ? Symbol.for("react.strict_mode") + ? Symbol["for"]("react.strict_mode") : 0xeacc; -var REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for("react.provider") : 0xeacd; -var REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for("react.context") : 0xeace; -var REACT_ASYNC_MODE_TYPE = hasSymbol ? Symbol.for("react.async_mode") : 0xeacf; +var REACT_PROVIDER_TYPE = hasSymbol ? Symbol["for"]("react.provider") : 0xeacd; +var REACT_CONTEXT_TYPE = hasSymbol ? Symbol["for"]("react.context") : 0xeace; +var REACT_ASYNC_MODE_TYPE = hasSymbol + ? Symbol["for"]("react.async_mode") + : 0xeacf; var REACT_FORWARD_REF_TYPE = hasSymbol - ? Symbol.for("react.forward_ref") + ? Symbol["for"]("react.forward_ref") : 0xead0; var MAYBE_ITERATOR_SYMBOL = typeof Symbol === "function" && Symbol.iterator; @@ -2846,7 +2847,7 @@ function getStackAddendumByWorkInProgressFiber(workInProgress) { do { info += describeFiber(node); // Otherwise this return pointer might point to the wrong tree: - node = node.return; + node = node["return"]; } while (node); return info; } @@ -3789,10 +3790,11 @@ var ContentReset = /* */ 16; var Callback = /* */ 32; var DidCapture = /* */ 64; var Ref = /* */ 128; -var Snapshot = /* */ 256; +var ErrLog = /* */ 256; +var Snapshot = /* */ 2048; // Union of all host effects -var HostEffectMask = /* */ 511; +var HostEffectMask = /* */ 2559; var Incomplete = /* */ 512; var ShouldCapture = /* */ 1024; @@ -3809,15 +3811,15 @@ function isFiberMountedImpl(fiber) { if ((node.effectTag & Placement) !== NoEffect) { return MOUNTING; } - while (node.return) { - node = node.return; + while (node["return"]) { + node = node["return"]; if ((node.effectTag & Placement) !== NoEffect) { return MOUNTING; } } } else { - while (node.return) { - node = node.return; + while (node["return"]) { + node = node["return"]; } } if (node.tag === HostRoot) { @@ -3889,7 +3891,7 @@ function findCurrentFiberUsingSlowPath(fiber) { var a = fiber; var b = alternate; while (true) { - var parentA = a.return; + var parentA = a["return"]; var parentB = parentA ? parentA.alternate : null; if (!parentA || !parentB) { // We're at the root. @@ -3919,7 +3921,7 @@ function findCurrentFiberUsingSlowPath(fiber) { invariant(false, "Unable to find node on an unmounted component."); } - if (a.return !== b.return) { + if (a["return"] !== b["return"]) { // The return pointer of A and the return pointer of B point to different // fibers. We assume that return pointers never criss-cross, so A must // belong to the child set of A.return, and B must belong to the child @@ -4007,7 +4009,7 @@ function findCurrentHostFiber(parent) { if (node.tag === HostComponent || node.tag === HostText) { return node; } else if (node.child) { - node.child.return = node; + node.child["return"] = node; node = node.child; continue; } @@ -4015,12 +4017,12 @@ function findCurrentHostFiber(parent) { return null; } while (!node.sibling) { - if (!node.return || node.return === currentParent) { + if (!node["return"] || node["return"] === currentParent) { return null; } - node = node.return; + node = node["return"]; } - node.sibling.return = node.return; + node.sibling["return"] = node["return"]; node = node.sibling; } // Flow needs the return null here, but ESLint complains about it. @@ -4040,7 +4042,7 @@ function findCurrentHostFiberWithNoPortals(parent) { if (node.tag === HostComponent || node.tag === HostText) { return node; } else if (node.child && node.tag !== HostPortal) { - node.child.return = node; + node.child["return"] = node; node = node.child; continue; } @@ -4048,12 +4050,12 @@ function findCurrentHostFiberWithNoPortals(parent) { return null; } while (!node.sibling) { - if (!node.return || node.return === currentParent) { + if (!node["return"] || node["return"] === currentParent) { return null; } - node = node.return; + node = node["return"]; } - node.sibling.return = node.return; + node.sibling["return"] = node["return"]; node = node.sibling; } // Flow needs the return null here, but ESLint complains about it. @@ -4136,7 +4138,7 @@ function FiberNode(tag, pendingProps, key, mode) { this.stateNode = null; // Fiber - this.return = null; + this["return"] = null; this.child = null; this.sibling = null; this.index = 0; @@ -4421,7 +4423,7 @@ function assignFiberPropertiesInDEV(target, source) { target.key = source.key; target.type = source.type; target.stateNode = source.stateNode; - target.return = source.return; + target["return"] = source["return"]; target.child = source.child; target.sibling = source.sibling; target.index = source.index; @@ -4704,7 +4706,7 @@ var ReactStrictModeWarnings = { maybeStrictRoot = fiber; } - fiber = fiber.return; + fiber = fiber["return"]; } return maybeStrictRoot; @@ -4825,6 +4827,16 @@ var ReactStrictModeWarnings = { return; } + // Don't warn about react-lifecycles-compat polyfilled components. + // Note that it is sufficient to check for the presence of a + // single lifecycle, componentWillMount, with the polyfill flag. + if ( + typeof instance.componentWillMount === "function" && + instance.componentWillMount.__suppressDeprecationWarning === true + ) { + return; + } + var warningsForRoot = void 0; if (!pendingUnsafeLifecycleWarnings.has(strictRoot)) { warningsForRoot = { @@ -4840,23 +4852,19 @@ var ReactStrictModeWarnings = { var unsafeLifecycles = []; if ( - (typeof instance.componentWillMount === "function" && - instance.componentWillMount.__suppressDeprecationWarning !== true) || + typeof instance.componentWillMount === "function" || typeof instance.UNSAFE_componentWillMount === "function" ) { unsafeLifecycles.push("UNSAFE_componentWillMount"); } if ( - (typeof instance.componentWillReceiveProps === "function" && - instance.componentWillReceiveProps.__suppressDeprecationWarning !== - true) || + typeof instance.componentWillReceiveProps === "function" || typeof instance.UNSAFE_componentWillReceiveProps === "function" ) { unsafeLifecycles.push("UNSAFE_componentWillReceiveProps"); } if ( - (typeof instance.componentWillUpdate === "function" && - instance.componentWillUpdate.__suppressDeprecationWarning !== true) || + typeof instance.componentWillUpdate === "function" || typeof instance.UNSAFE_componentWillUpdate === "function" ) { unsafeLifecycles.push("UNSAFE_componentWillUpdate"); @@ -4896,7 +4904,7 @@ function getCurrentFiberOwnerName() { return null; } -function getCurrentFiberStackAddendum$1() { +function getCurrentFiberStackAddendum() { { var fiber = ReactDebugCurrentFiber.current; if (fiber === null) { @@ -4916,7 +4924,7 @@ function resetCurrentFiber() { } function setCurrentFiber(fiber) { - ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackAddendum$1; + ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackAddendum; ReactDebugCurrentFiber.current = fiber; ReactDebugCurrentFiber.phase = null; } @@ -4932,7 +4940,7 @@ var ReactDebugCurrentFiber = { setCurrentFiber: setCurrentFiber, setCurrentPhase: setCurrentPhase, getCurrentFiberOwnerName: getCurrentFiberOwnerName, - getCurrentFiberStackAddendum: getCurrentFiberStackAddendum$1 + getCurrentFiberStackAddendum: getCurrentFiberStackAddendum }; // Prefix measurements so that it's possible to filter them. @@ -5089,13 +5097,13 @@ var pauseTimers = function() { if (fiber._debugIsCurrentlyTiming) { endFiberMark(fiber, null, null); } - fiber = fiber.return; + fiber = fiber["return"]; } }; var resumeTimersRecursively = function(fiber) { - if (fiber.return !== null) { - resumeTimersRecursively(fiber.return); + if (fiber["return"] !== null) { + resumeTimersRecursively(fiber["return"]); } if (fiber._debugIsCurrentlyTiming) { beginFiberMark(fiber, null); @@ -5187,7 +5195,7 @@ function stopWorkTimer(fiber) { return; } // If we pause, its parent is the fiber to unwind from. - currentFiber = fiber.return; + currentFiber = fiber["return"]; if (!fiber._debugIsCurrentlyTiming) { return; } @@ -5202,7 +5210,7 @@ function stopFailedWorkTimer(fiber) { return; } // If we pause, its parent is the fiber to unwind from. - currentFiber = fiber.return; + currentFiber = fiber["return"]; if (!fiber._debugIsCurrentlyTiming) { return; } @@ -5392,232 +5400,100 @@ function stopCommitLifeCyclesTimer() { } } -// UpdateQueue is a linked list of prioritized updates. -// -// Like fibers, update queues come in pairs: a current queue, which represents -// the visible state of the screen, and a work-in-progress queue, which is -// can be mutated and processed asynchronously before it is committed — a form -// of double buffering. If a work-in-progress render is discarded before -// finishing, we create a new work-in-progress by cloning the current queue. -// -// Both queues share a persistent, singly-linked list structure. To schedule an -// update, we append it to the end of both queues. Each queue maintains a -// pointer to first update in the persistent list that hasn't been processed. -// The work-in-progress pointer always has a position equal to or greater than -// the current queue, since we always work on that one. The current queue's -// pointer is only updated during the commit phase, when we swap in the -// work-in-progress. -// -// For example: -// -// Current pointer: A - B - C - D - E - F -// Work-in-progress pointer: D - E - F -// ^ -// The work-in-progress queue has -// processed more updates than current. -// -// The reason we append to both queues is because otherwise we might drop -// updates without ever processing them. For example, if we only add updates to -// the work-in-progress queue, some updates could be lost whenever a work-in -// -progress render restarts by cloning from current. Similarly, if we only add -// updates to the current queue, the updates will be lost whenever an already -// in-progress queue commits and swaps with the current queue. However, by -// adding to both queues, we guarantee that the update will be part of the next -// work-in-progress. (And because the work-in-progress queue becomes the -// current queue once it commits, there's no danger of applying the same -// update twice.) -// -// Prioritization -// -------------- -// -// Updates are not sorted by priority, but by insertion; new updates are always -// appended to the end of the list. -// -// The priority is still important, though. When processing the update queue -// during the render phase, only the updates with sufficient priority are -// included in the result. If we skip an update because it has insufficient -// priority, it remains in the queue to be processed later, during a lower -// priority render. Crucially, all updates subsequent to a skipped update also -// remain in the queue *regardless of their priority*. That means high priority -// updates are sometimes processed twice, at two separate priorities. We also -// keep track of a base state, that represents the state before the first -// update in the queue is applied. -// -// For example: -// -// Given a base state of '', and the following queue of updates -// -// A1 - B2 - C1 - D2 -// -// where the number indicates the priority, and the update is applied to the -// previous state by appending a letter, React will process these updates as -// two separate renders, one per distinct priority level: -// -// First render, at priority 1: -// Base state: '' -// Updates: [A1, C1] -// Result state: 'AC' -// -// Second render, at priority 2: -// Base state: 'A' <- The base state does not include C1, -// because B2 was skipped. -// Updates: [B2, C1, D2] <- C1 was rebased on top of B2 -// Result state: 'ABCD' -// -// Because we process updates in insertion order, and rebase high priority -// updates when preceding updates are skipped, the final result is deterministic -// regardless of priority. Intermediate state may vary according to system -// resources, but the final state is always the same. - -var UpdateState = 0; -var ReplaceState = 1; -var ForceUpdate = 2; -var CaptureUpdate = 3; - var didWarnUpdateInsideUpdate = void 0; -var currentlyProcessingQueue = void 0; -var resetCurrentlyProcessingQueue = void 0; + { didWarnUpdateInsideUpdate = false; - currentlyProcessingQueue = null; - resetCurrentlyProcessingQueue = function() { - currentlyProcessingQueue = null; - }; } +// Callbacks are not validated until invocation + +// Singly linked-list of updates. When an update is scheduled, it is added to +// the queue of the current fiber and the work-in-progress fiber. The two queues +// are separate but they share a persistent structure. +// +// During reconciliation, updates are removed from the work-in-progress fiber, +// but they remain on the current fiber. That ensures that if a work-in-progress +// is aborted, the aborted updates are recovered by cloning from current. +// +// The work-in-progress queue is always a subset of the current queue. +// +// When the tree is committed, the work-in-progress becomes the current. + function createUpdateQueue(baseState) { var queue = { - expirationTime: NoWork, baseState: baseState, - firstUpdate: null, - lastUpdate: null, - firstCapturedUpdate: null, - lastCapturedUpdate: null, - firstEffect: null, - lastEffect: null, - firstCapturedEffect: null, - lastCapturedEffect: null, - hasForceUpdate: false - }; - return queue; -} - -function cloneUpdateQueue(currentQueue) { - var queue = { - expirationTime: currentQueue.expirationTime, - baseState: currentQueue.baseState, - firstUpdate: currentQueue.firstUpdate, - lastUpdate: currentQueue.lastUpdate, - - // TODO: With resuming, if we bail out and resuse the child tree, we should - // keep these effects. - firstCapturedUpdate: null, - lastCapturedUpdate: null, - + expirationTime: NoWork, + first: null, + last: null, + callbackList: null, hasForceUpdate: false, - - firstEffect: null, - lastEffect: null, - - firstCapturedEffect: null, - lastCapturedEffect: null + isInitialized: false, + capturedValues: null }; + { + queue.isProcessing = false; + } return queue; } -function createUpdate(expirationTime) { - return { - expirationTime: expirationTime, - - tag: UpdateState, - payload: null, - callback: null, - - next: null, - nextEffect: null - }; -} - -function appendUpdateToQueue(queue, update, expirationTime) { +function insertUpdateIntoQueue(queue, update) { // Append the update to the end of the list. - if (queue.lastUpdate === null) { + if (queue.last === null) { // Queue is empty - queue.firstUpdate = queue.lastUpdate = update; + queue.first = queue.last = update; } else { - queue.lastUpdate.next = update; - queue.lastUpdate = update; + queue.last.next = update; + queue.last = update; } if ( queue.expirationTime === NoWork || - queue.expirationTime > expirationTime + queue.expirationTime > update.expirationTime ) { - // The incoming update has the earliest expiration of any update in the - // queue. Update the queue's expiration time. - queue.expirationTime = expirationTime; + queue.expirationTime = update.expirationTime; } } -function enqueueUpdate(fiber, update, expirationTime) { - // Update queues are created lazily. - var alternate = fiber.alternate; - var queue1 = void 0; - var queue2 = void 0; - if (alternate === null) { - // There's only one fiber. - queue1 = fiber.updateQueue; - queue2 = null; - if (queue1 === null) { - queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState); - } - } else { - // There are two owners. - queue1 = fiber.updateQueue; - queue2 = alternate.updateQueue; - if (queue1 === null) { - if (queue2 === null) { - // Neither fiber has an update queue. Create new ones. - queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState); - queue2 = alternate.updateQueue = createUpdateQueue( - alternate.memoizedState - ); - } else { - // Only one fiber has an update queue. Clone to create a new one. - queue1 = fiber.updateQueue = cloneUpdateQueue(queue2); - } - } else { - if (queue2 === null) { - // Only one fiber has an update queue. Clone to create a new one. - queue2 = alternate.updateQueue = cloneUpdateQueue(queue1); - } else { - // Both owners have an update queue. - } - } - } - if (queue2 === null || queue1 === queue2) { - // There's only a single queue. - appendUpdateToQueue(queue1, update, expirationTime); - } else { - // There are two queues. We need to append the update to both queues, - // while accounting for the persistent structure of the list — we don't - // want the same update to be added multiple times. - if (queue1.lastUpdate === null || queue2.lastUpdate === null) { - // One of the queues is not empty. We must add the update to both queues. - appendUpdateToQueue(queue1, update, expirationTime); - appendUpdateToQueue(queue2, update, expirationTime); - } else { - // Both queues are non-empty. The last update is the same in both lists, - // because of structural sharing. So, only append to one of the lists. - appendUpdateToQueue(queue1, update, expirationTime); - // But we still need to update the `lastUpdate` pointer of queue2. - queue2.lastUpdate = update; - } +var q1 = void 0; +var q2 = void 0; +function ensureUpdateQueues(fiber) { + q1 = q2 = null; + // We'll have at least one and at most two distinct update queues. + var alternateFiber = fiber.alternate; + var queue1 = fiber.updateQueue; + if (queue1 === null) { + // TODO: We don't know what the base state will be until we begin work. + // It depends on which fiber is the next current. Initialize with an empty + // base state, then set to the memoizedState when rendering. Not super + // happy with this approach. + queue1 = fiber.updateQueue = createUpdateQueue(null); } + var queue2 = void 0; + if (alternateFiber !== null) { + queue2 = alternateFiber.updateQueue; + if (queue2 === null) { + queue2 = alternateFiber.updateQueue = createUpdateQueue(null); + } + } else { + queue2 = null; + } + queue2 = queue2 !== queue1 ? queue2 : null; + + // Use module variables instead of returning a tuple + q1 = queue1; + q2 = queue2; +} + +function insertUpdateIntoFiber(fiber, update) { + ensureUpdateQueues(fiber); + var queue1 = q1; + var queue2 = q2; + + // Warn if an update is scheduled from inside an updater function. { if ( - fiber.tag === ClassComponent && - (currentlyProcessingQueue === queue1 || - (queue2 !== null && currentlyProcessingQueue === queue2)) && + (queue1.isProcessing || (queue2 !== null && queue2.isProcessing)) && !didWarnUpdateInsideUpdate ) { warning( @@ -5630,328 +5506,225 @@ function enqueueUpdate(fiber, update, expirationTime) { didWarnUpdateInsideUpdate = true; } } -} -function enqueueCapturedUpdate(workInProgress, update, renderExpirationTime) { - // Captured updates go into a separate list, and only on the work-in- - // progress queue. - var workInProgressQueue = workInProgress.updateQueue; - if (workInProgressQueue === null) { - workInProgressQueue = workInProgress.updateQueue = createUpdateQueue( - workInProgress.memoizedState - ); - } else { - // TODO: I put this here rather than createWorkInProgress so that we don't - // clone the queue unnecessarily. There's probably a better way to - // structure this. - workInProgressQueue = ensureWorkInProgressQueueIsAClone( - workInProgress, - workInProgressQueue - ); - } - - // Append the update to the end of the list. - if (workInProgressQueue.lastCapturedUpdate === null) { - // This is the first render phase update - workInProgressQueue.firstCapturedUpdate = workInProgressQueue.lastCapturedUpdate = update; - } else { - workInProgressQueue.lastCapturedUpdate.next = update; - workInProgressQueue.lastCapturedUpdate = update; - } - if ( - workInProgressQueue.expirationTime === NoWork || - workInProgressQueue.expirationTime > renderExpirationTime - ) { - // The incoming update has the earliest expiration of any update in the - // queue. Update the queue's expiration time. - workInProgressQueue.expirationTime = renderExpirationTime; - } -} - -function ensureWorkInProgressQueueIsAClone(workInProgress, queue) { - var current = workInProgress.alternate; - if (current !== null) { - // If the work-in-progress queue is equal to the current queue, - // we need to clone it first. - if (queue === current.updateQueue) { - queue = workInProgress.updateQueue = cloneUpdateQueue(queue); - } - } - return queue; -} - -function getStateFromUpdate( - workInProgress, - queue, - update, - prevState, - nextProps, - instance -) { - switch (update.tag) { - case ReplaceState: { - var _payload = update.payload; - if (typeof _payload === "function") { - // Updater function - { - if ( - debugRenderPhaseSideEffects || - (debugRenderPhaseSideEffectsForStrictMode && - workInProgress.mode & StrictMode) - ) { - _payload.call(instance, prevState, nextProps); - } - } - return _payload.call(instance, prevState, nextProps); - } - // State object - return _payload; - } - case CaptureUpdate: { - workInProgress.effectTag = - (workInProgress.effectTag & ~ShouldCapture) | DidCapture; - } - // Intentional fallthrough - case UpdateState: { - var _payload2 = update.payload; - var partialState = void 0; - if (typeof _payload2 === "function") { - // Updater function - { - if ( - debugRenderPhaseSideEffects || - (debugRenderPhaseSideEffectsForStrictMode && - workInProgress.mode & StrictMode) - ) { - _payload2.call(instance, prevState, nextProps); - } - } - partialState = _payload2.call(instance, prevState, nextProps); - } else { - // Partial state object - partialState = _payload2; - } - if (partialState === null || partialState === undefined) { - // Null and undefined are treated as no-ops. - return prevState; - } - // Merge the partial state and the previous state. - return Object.assign({}, prevState, partialState); - } - case ForceUpdate: { - queue.hasForceUpdate = true; - return prevState; - } - } - return prevState; -} - -function processUpdateQueue( - workInProgress, - queue, - props, - instance, - renderExpirationTime -) { - if ( - queue.expirationTime === NoWork || - queue.expirationTime > renderExpirationTime - ) { - // Insufficient priority. Bailout. + // If there's only one queue, add the update to that queue and exit. + if (queue2 === null) { + insertUpdateIntoQueue(queue1, update); return; } - queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue); - - { - currentlyProcessingQueue = queue; + // If either queue is empty, we need to add to both queues. + if (queue1.last === null || queue2.last === null) { + insertUpdateIntoQueue(queue1, update); + insertUpdateIntoQueue(queue2, update); + return; } - // These values may change as we process the queue. - var newBaseState = queue.baseState; - var newFirstUpdate = null; - var newExpirationTime = NoWork; + // If both lists are not empty, the last update is the same for both lists + // because of structural sharing. So, we should only append to one of + // the lists. + insertUpdateIntoQueue(queue1, update); + // But we still need to update the `last` pointer of queue2. + queue2.last = update; +} - // Iterate through the list of updates to compute the result. - var update = queue.firstUpdate; - var resultState = newBaseState; +function getUpdateExpirationTime(fiber) { + switch (fiber.tag) { + case HostRoot: + case ClassComponent: + var updateQueue = fiber.updateQueue; + if (updateQueue === null) { + return NoWork; + } + return updateQueue.expirationTime; + default: + return NoWork; + } +} + +function getStateFromUpdate(update, instance, prevState, props) { + var partialState = update.partialState; + if (typeof partialState === "function") { + return partialState.call(instance, prevState, props); + } else { + return partialState; + } +} + +function processUpdateQueue( + current, + workInProgress, + queue, + instance, + props, + renderExpirationTime +) { + if (current !== null && current.updateQueue === queue) { + // We need to create a work-in-progress queue, by cloning the current queue. + var currentQueue = queue; + queue = workInProgress.updateQueue = { + baseState: currentQueue.baseState, + expirationTime: currentQueue.expirationTime, + first: currentQueue.first, + last: currentQueue.last, + isInitialized: currentQueue.isInitialized, + capturedValues: currentQueue.capturedValues, + // These fields are no longer valid because they were already committed. + // Reset them. + callbackList: null, + hasForceUpdate: false + }; + } + + { + // Set this flag so we can warn if setState is called inside the update + // function of another setState. + queue.isProcessing = true; + } + + // Reset the remaining expiration time. If we skip over any updates, we'll + // increase this accordingly. + queue.expirationTime = NoWork; + + // TODO: We don't know what the base state will be until we begin work. + // It depends on which fiber is the next current. Initialize with an empty + // base state, then set to the memoizedState when rendering. Not super + // happy with this approach. + var state = void 0; + if (queue.isInitialized) { + state = queue.baseState; + } else { + state = queue.baseState = workInProgress.memoizedState; + queue.isInitialized = true; + } + var dontMutatePrevState = true; + var update = queue.first; + var didSkip = false; while (update !== null) { var updateExpirationTime = update.expirationTime; if (updateExpirationTime > renderExpirationTime) { // This update does not have sufficient priority. Skip it. - if (newFirstUpdate === null) { - // This is the first skipped update. It will be the first update in - // the new list. - newFirstUpdate = update; - // Since this is the first update that was skipped, the current result - // is the new base state. - newBaseState = resultState; - } - // Since this update will remain in the list, update the remaining - // expiration time. + var remainingExpirationTime = queue.expirationTime; if ( - newExpirationTime === NoWork || - newExpirationTime > updateExpirationTime + remainingExpirationTime === NoWork || + remainingExpirationTime > updateExpirationTime ) { - newExpirationTime = updateExpirationTime; + // Update the remaining expiration time. + queue.expirationTime = updateExpirationTime; } - } else { - // This update does have sufficient priority. Process it and compute - // a new result. - resultState = getStateFromUpdate( - workInProgress, - queue, - update, - resultState, - props, - instance - ); - var _callback = update.callback; - if (_callback !== null) { - workInProgress.effectTag |= Callback; - // Set this to null, in case it was mutated during an aborted render. - update.nextEffect = null; - if (queue.lastEffect === null) { - queue.firstEffect = queue.lastEffect = update; - } else { - queue.lastEffect.nextEffect = update; - queue.lastEffect = update; - } + if (!didSkip) { + didSkip = true; + queue.baseState = state; + } + // Continue to the next update. + update = update.next; + continue; + } + + // This update does have sufficient priority. + + // If no previous updates were skipped, drop this update from the queue by + // advancing the head of the list. + if (!didSkip) { + queue.first = update.next; + if (queue.first === null) { + queue.last = null; } } - // Continue to the next update. - update = update.next; - } - // Separately, iterate though the list of captured updates. - var newFirstCapturedUpdate = null; - update = queue.firstCapturedUpdate; - while (update !== null) { - var _updateExpirationTime = update.expirationTime; - if (_updateExpirationTime > renderExpirationTime) { - // This update does not have sufficient priority. Skip it. - if (newFirstCapturedUpdate === null) { - // This is the first skipped captured update. It will be the first - // update in the new list. - newFirstCapturedUpdate = update; - // If this is the first update that was skipped, the current result is - // the new base state. - if (newFirstUpdate === null) { - newBaseState = resultState; - } - } - // Since this update will remain in the list, update the remaining - // expiration time. - if ( - newExpirationTime === NoWork || - newExpirationTime > _updateExpirationTime - ) { - newExpirationTime = _updateExpirationTime; - } + // Invoke setState callback an extra time to help detect side-effects. + // Ignore the return value in this case. + if ( + debugRenderPhaseSideEffects || + (debugRenderPhaseSideEffectsForStrictMode && + workInProgress.mode & StrictMode) + ) { + getStateFromUpdate(update, instance, state, props); + } + + // Process the update + var _partialState = void 0; + if (update.isReplace) { + state = getStateFromUpdate(update, instance, state, props); + dontMutatePrevState = true; } else { - // This update does have sufficient priority. Process it and compute - // a new result. - resultState = getStateFromUpdate( - workInProgress, - queue, - update, - resultState, - props, - instance - ); - var _callback2 = update.callback; - if (_callback2 !== null) { - workInProgress.effectTag |= Callback; - // Set this to null, in case it was mutated during an aborted render. - update.nextEffect = null; - if (queue.lastCapturedEffect === null) { - queue.firstCapturedEffect = queue.lastCapturedEffect = update; + _partialState = getStateFromUpdate(update, instance, state, props); + if (_partialState) { + if (dontMutatePrevState) { + // $FlowFixMe: Idk how to type this properly. + state = Object.assign({}, state, _partialState); } else { - queue.lastCapturedEffect.nextEffect = update; - queue.lastCapturedEffect = update; + state = Object.assign(state, _partialState); } + dontMutatePrevState = false; + } + } + if (update.isForced) { + queue.hasForceUpdate = true; + } + if (update.callback !== null) { + // Append to list of callbacks. + var _callbackList = queue.callbackList; + if (_callbackList === null) { + _callbackList = queue.callbackList = []; + } + _callbackList.push(update); + } + if (update.capturedValue !== null) { + var _capturedValues = queue.capturedValues; + if (_capturedValues === null) { + queue.capturedValues = [update.capturedValue]; + } else { + _capturedValues.push(update.capturedValue); } } update = update.next; } - if (newFirstUpdate === null) { - queue.lastUpdate = null; - } - if (newFirstCapturedUpdate === null) { - queue.lastCapturedUpdate = null; - } else { + if (queue.callbackList !== null) { workInProgress.effectTag |= Callback; - } - if (newFirstUpdate === null && newFirstCapturedUpdate === null) { - // We processed every update, without skipping. That means the new base - // state is the same as the result state. - newBaseState = resultState; + } else if ( + queue.first === null && + !queue.hasForceUpdate && + queue.capturedValues === null + ) { + // The queue is empty. We can reset it. + workInProgress.updateQueue = null; } - queue.baseState = newBaseState; - queue.firstUpdate = newFirstUpdate; - queue.firstCapturedUpdate = newFirstCapturedUpdate; - queue.expirationTime = newExpirationTime; - - workInProgress.memoizedState = resultState; + if (!didSkip) { + didSkip = true; + queue.baseState = state; + } { - currentlyProcessingQueue = null; + // No longer processing. + queue.isProcessing = false; } + + return state; } -function callCallback(callback, context) { - invariant( - typeof callback === "function", - "Invalid argument passed as callback. Expected a function. Instead " + - "received: %s", - callback - ); - callback.call(context); -} - -function commitUpdateQueue( - finishedWork, - finishedQueue, - instance, - renderExpirationTime -) { - // If the finished render included captured updates, and there are still - // lower priority updates left over, we need to keep the captured updates - // in the queue so that they are rebased and not dropped once we process the - // queue again at the lower priority. - if (finishedQueue.firstCapturedUpdate !== null) { - // Join the captured update list to the end of the normal list. - if (finishedQueue.lastUpdate !== null) { - finishedQueue.lastUpdate.next = finishedQueue.firstCapturedUpdate; - finishedQueue.lastUpdate = finishedQueue.lastCapturedUpdate; - } - // Clear the list of captured updates. - finishedQueue.firstCapturedUpdate = finishedQueue.lastCapturedUpdate = null; +function commitCallbacks(queue, context) { + var callbackList = queue.callbackList; + if (callbackList === null) { + return; } - - // Commit the effects - var effect = finishedQueue.firstEffect; - finishedQueue.firstEffect = finishedQueue.lastEffect = null; - while (effect !== null) { - var _callback3 = effect.callback; - if (_callback3 !== null) { - effect.callback = null; - callCallback(_callback3, instance); - } - effect = effect.nextEffect; - } - - effect = finishedQueue.firstCapturedEffect; - finishedQueue.firstCapturedEffect = finishedQueue.lastCapturedEffect = null; - while (effect !== null) { - var _callback4 = effect.callback; - if (_callback4 !== null) { - effect.callback = null; - callCallback(_callback4, instance); - } - effect = effect.nextEffect; + // Set the list to null to make sure they don't get called more than once. + queue.callbackList = null; + for (var i = 0; i < callbackList.length; i++) { + var update = callbackList[i]; + var _callback = update.callback; + // This update might be processed again. Clear the callback so it's only + // called once. + update.callback = null; + invariant( + typeof _callback === "function", + "Invalid argument passed as callback. Expected a function. Instead " + + "received: %s", + _callback + ); + _callback.call(context); } } @@ -5959,19 +5732,18 @@ var fakeInternalInstance = {}; var isArray = Array.isArray; var didWarnAboutStateAssignmentForComponent = void 0; +var didWarnAboutUndefinedDerivedState = void 0; var didWarnAboutUninitializedState = void 0; var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = void 0; var didWarnAboutLegacyLifecyclesAndDerivedState = void 0; -var didWarnAboutUndefinedDerivedState = void 0; -var warnOnUndefinedDerivedState = void 0; var warnOnInvalidCallback = void 0; { didWarnAboutStateAssignmentForComponent = new Set(); + didWarnAboutUndefinedDerivedState = new Set(); didWarnAboutUninitializedState = new Set(); didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set(); didWarnAboutLegacyLifecyclesAndDerivedState = new Set(); - didWarnAboutUndefinedDerivedState = new Set(); var didWarnOnInvalidCallback = new Set(); @@ -5992,21 +5764,6 @@ var warnOnInvalidCallback = void 0; } }; - warnOnUndefinedDerivedState = function(workInProgress, partialState) { - if (partialState === undefined) { - var componentName = getComponentName(workInProgress) || "Component"; - if (!didWarnAboutUndefinedDerivedState.has(componentName)) { - didWarnAboutUndefinedDerivedState.add(componentName); - warning( - false, - "%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. " + - "You have returned undefined.", - componentName - ); - } - } - }; - // This is so gross but it's at least non-critical and can be removed if // it causes problems. This is meant to give a nicer error message for // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component, @@ -6028,43 +5785,17 @@ var warnOnInvalidCallback = void 0; }); Object.freeze(fakeInternalInstance); } - -function applyDerivedStateFromProps( - workInProgress, - getDerivedStateFromProps, - nextProps -) { - var prevState = workInProgress.memoizedState; - - { - if ( - debugRenderPhaseSideEffects || - (debugRenderPhaseSideEffectsForStrictMode && - workInProgress.mode & StrictMode) - ) { - // Invoke the function an extra time to help detect side-effects. - getDerivedStateFromProps(nextProps, prevState); +function callGetDerivedStateFromCatch(ctor, capturedValues) { + var resultState = {}; + for (var i = 0; i < capturedValues.length; i++) { + var capturedValue = capturedValues[i]; + var error = capturedValue.value; + var partialState = ctor.getDerivedStateFromCatch.call(null, error); + if (partialState !== null && partialState !== undefined) { + Object.assign(resultState, partialState); } } - - var partialState = getDerivedStateFromProps(nextProps, prevState); - - { - warnOnUndefinedDerivedState(workInProgress, partialState); - } - // Merge the partial state and the previous state. - var memoizedState = - partialState === null || partialState === undefined - ? prevState - : Object.assign({}, prevState, partialState); - workInProgress.memoizedState = memoizedState; - - // Once the update queue is empty, persist the derived state onto the - // base state. - var updateQueue = workInProgress.updateQueue; - if (updateQueue !== null && updateQueue.expirationTime === NoWork) { - updateQueue.baseState = memoizedState; - } + return resultState; } var ReactFiberClassComponent = function( @@ -6080,57 +5811,65 @@ var ReactFiberClassComponent = function( isContextConsumer = legacyContext.isContextConsumer, hasContextChanged = legacyContext.hasContextChanged; - var classComponentUpdater = { + // Class component state updater + + var updater = { isMounted: isMounted, - enqueueSetState: function(inst, payload, callback) { - var fiber = get$1(inst); - var expirationTime = computeExpirationForFiber(fiber); - - var update = createUpdate(expirationTime); - update.payload = payload; - if (callback !== undefined && callback !== null) { - { - warnOnInvalidCallback(callback, "setState"); - } - update.callback = callback; + enqueueSetState: function(instance, partialState, callback) { + var fiber = get$1(instance); + callback = callback === undefined ? null : callback; + { + warnOnInvalidCallback(callback, "setState"); } - - enqueueUpdate(fiber, update, expirationTime); + var expirationTime = computeExpirationForFiber(fiber); + var update = { + expirationTime: expirationTime, + partialState: partialState, + callback: callback, + isReplace: false, + isForced: false, + capturedValue: null, + next: null + }; + insertUpdateIntoFiber(fiber, update); scheduleWork(fiber, expirationTime); }, - enqueueReplaceState: function(inst, payload, callback) { - var fiber = get$1(inst); - var expirationTime = computeExpirationForFiber(fiber); - - var update = createUpdate(expirationTime); - update.tag = ReplaceState; - update.payload = payload; - - if (callback !== undefined && callback !== null) { - { - warnOnInvalidCallback(callback, "replaceState"); - } - update.callback = callback; + enqueueReplaceState: function(instance, state, callback) { + var fiber = get$1(instance); + callback = callback === undefined ? null : callback; + { + warnOnInvalidCallback(callback, "replaceState"); } - - enqueueUpdate(fiber, update, expirationTime); + var expirationTime = computeExpirationForFiber(fiber); + var update = { + expirationTime: expirationTime, + partialState: state, + callback: callback, + isReplace: true, + isForced: false, + capturedValue: null, + next: null + }; + insertUpdateIntoFiber(fiber, update); scheduleWork(fiber, expirationTime); }, - enqueueForceUpdate: function(inst, callback) { - var fiber = get$1(inst); - var expirationTime = computeExpirationForFiber(fiber); - - var update = createUpdate(expirationTime); - update.tag = ForceUpdate; - - if (callback !== undefined && callback !== null) { - { - warnOnInvalidCallback(callback, "forceUpdate"); - } - update.callback = callback; + enqueueForceUpdate: function(instance, callback) { + var fiber = get$1(instance); + callback = callback === undefined ? null : callback; + { + warnOnInvalidCallback(callback, "forceUpdate"); } - - enqueueUpdate(fiber, update, expirationTime); + var expirationTime = computeExpirationForFiber(fiber); + var update = { + expirationTime: expirationTime, + partialState: null, + callback: callback, + isReplace: false, + isForced: true, + capturedValue: null, + next: null + }; + insertUpdateIntoFiber(fiber, update); scheduleWork(fiber, expirationTime); } }; @@ -6144,10 +5883,11 @@ var ReactFiberClassComponent = function( newContext ) { if ( - workInProgress.updateQueue !== null && - workInProgress.updateQueue.hasForceUpdate + oldProps === null || + (workInProgress.updateQueue !== null && + workInProgress.updateQueue.hasForceUpdate) ) { - // If forceUpdate was called, disregard sCU. + // If the workInProgress already has an Update effect, return true return true; } @@ -6404,8 +6144,13 @@ var ReactFiberClassComponent = function( } } + function resetInputPointers(workInProgress, instance) { + instance.props = workInProgress.memoizedProps; + instance.state = workInProgress.memoizedState; + } + function adoptClassInstance(workInProgress, instance) { - instance.updater = classComponentUpdater; + instance.updater = updater; workInProgress.stateNode = instance; // The instance needs access to the fiber so that it can schedule updates set(instance, workInProgress); @@ -6414,7 +6159,7 @@ var ReactFiberClassComponent = function( } } - function constructClassInstance(workInProgress, props, renderExpirationTime) { + function constructClassInstance(workInProgress, props) { var ctor = workInProgress.type; var unmaskedContext = getUnmaskedContext(workInProgress); var needsContext = isContextConsumer(workInProgress); @@ -6423,21 +6168,19 @@ var ReactFiberClassComponent = function( : emptyObject; // Instantiate twice to help detect side-effects. - { - if ( - debugRenderPhaseSideEffects || - (debugRenderPhaseSideEffectsForStrictMode && - workInProgress.mode & StrictMode) - ) { - new ctor(props, context); // eslint-disable-line no-new - } + if ( + debugRenderPhaseSideEffects || + (debugRenderPhaseSideEffectsForStrictMode && + workInProgress.mode & StrictMode) + ) { + new ctor(props, context); // eslint-disable-line no-new } var instance = new ctor(props, context); - var state = (workInProgress.memoizedState = + var state = instance.state !== null && instance.state !== undefined ? instance.state - : null); + : null; adoptClassInstance(workInProgress, instance); { @@ -6528,6 +6271,26 @@ var ReactFiberClassComponent = function( } } + workInProgress.memoizedState = state; + + var partialState = callGetDerivedStateFromProps( + workInProgress, + instance, + props, + state + ); + + if (partialState !== null && partialState !== undefined) { + // Render-phase updates (like this) should not be added to the update queue, + // So that multiple render passes do not enqueue multiple updates. + // Instead, just synchronously merge the returned state into the instance. + workInProgress.memoizedState = Object.assign( + {}, + workInProgress.memoizedState, + partialState + ); + } + // Cache unmasked context so we can avoid recreating masked context unless necessary. // ReactFiberContext usually updates this cache but can't for newly-created instances. if (needsContext) { @@ -6560,7 +6323,7 @@ var ReactFiberClassComponent = function( getComponentName(workInProgress) || "Component" ); } - classComponentUpdater.enqueueReplaceState(instance, instance.state, null); + updater.enqueueReplaceState(instance, instance.state, null); } } @@ -6594,13 +6357,57 @@ var ReactFiberClassComponent = function( ); } } - classComponentUpdater.enqueueReplaceState(instance, instance.state, null); + updater.enqueueReplaceState(instance, instance.state, null); + } + } + + function callGetDerivedStateFromProps( + workInProgress, + instance, + nextProps, + prevState + ) { + var type = workInProgress.type; + + if (typeof type.getDerivedStateFromProps === "function") { + if ( + debugRenderPhaseSideEffects || + (debugRenderPhaseSideEffectsForStrictMode && + workInProgress.mode & StrictMode) + ) { + // Invoke method an extra time to help detect side-effects. + type.getDerivedStateFromProps.call(null, nextProps, prevState); + } + + var partialState = type.getDerivedStateFromProps.call( + null, + nextProps, + prevState + ); + + { + if (partialState === undefined) { + var componentName = getComponentName(workInProgress) || "Component"; + if (!didWarnAboutUndefinedDerivedState.has(componentName)) { + didWarnAboutUndefinedDerivedState.add(componentName); + warning( + false, + "%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. " + + "You have returned undefined.", + componentName + ); + } + } + } + + return partialState; } } // Invokes the mount life-cycles on a previously never rendered instance. function mountClassInstance(workInProgress, renderExpirationTime) { var ctor = workInProgress.type; + var current = workInProgress.alternate; { checkClassInstance(workInProgress); @@ -6631,28 +6438,6 @@ var ReactFiberClassComponent = function( } } - var updateQueue = workInProgress.updateQueue; - if (updateQueue !== null) { - processUpdateQueue( - workInProgress, - updateQueue, - props, - instance, - renderExpirationTime - ); - instance.state = workInProgress.memoizedState; - } - - var getDerivedStateFromProps = workInProgress.type.getDerivedStateFromProps; - if (typeof getDerivedStateFromProps === "function") { - applyDerivedStateFromProps( - workInProgress, - getDerivedStateFromProps, - props - ); - instance.state = workInProgress.memoizedState; - } - // In order to support react-lifecycles-compat polyfilled components, // Unsafe lifecycles should not be invoked for components using the new APIs. if ( @@ -6664,19 +6449,18 @@ var ReactFiberClassComponent = function( callComponentWillMount(workInProgress, instance); // If we had additional state updates during this life-cycle, let's // process them now. - updateQueue = workInProgress.updateQueue; + var updateQueue = workInProgress.updateQueue; if (updateQueue !== null) { - processUpdateQueue( + instance.state = processUpdateQueue( + current, workInProgress, updateQueue, - props, instance, + props, renderExpirationTime ); - instance.state = workInProgress.memoizedState; } } - if (typeof instance.componentDidMount === "function") { workInProgress.effectTag |= Update; } @@ -6685,18 +6469,16 @@ var ReactFiberClassComponent = function( function resumeMountClassInstance(workInProgress, renderExpirationTime) { var ctor = workInProgress.type; var instance = workInProgress.stateNode; + resetInputPointers(workInProgress, instance); var oldProps = workInProgress.memoizedProps; var newProps = workInProgress.pendingProps; - instance.props = oldProps; - var oldContext = instance.context; var newUnmaskedContext = getUnmaskedContext(workInProgress); var newContext = getMaskedContext(workInProgress, newUnmaskedContext); - var getDerivedStateFromProps = ctor.getDerivedStateFromProps; var hasNewLifecycles = - typeof getDerivedStateFromProps === "function" || + typeof ctor.getDerivedStateFromProps === "function" || typeof instance.getSnapshotBeforeUpdate === "function"; // Note: During these life-cycles, instance.props/instance.state are what @@ -6720,27 +6502,93 @@ var ReactFiberClassComponent = function( } } + // Compute the next state using the memoized state and the update queue. var oldState = workInProgress.memoizedState; - var newState = (instance.state = oldState); - var updateQueue = workInProgress.updateQueue; - if (updateQueue !== null) { - processUpdateQueue( + // TODO: Previous state can be null. + var newState = void 0; + var derivedStateFromCatch = void 0; + if (workInProgress.updateQueue !== null) { + newState = processUpdateQueue( + null, workInProgress, - updateQueue, - newProps, + workInProgress.updateQueue, instance, + newProps, renderExpirationTime ); - newState = workInProgress.memoizedState; + + var updateQueue = workInProgress.updateQueue; + if ( + updateQueue !== null && + updateQueue.capturedValues !== null && + enableGetDerivedStateFromCatch && + typeof ctor.getDerivedStateFromCatch === "function" + ) { + var capturedValues = updateQueue.capturedValues; + // Don't remove these from the update queue yet. We need them in + // finishClassComponent. Do the reset there. + // TODO: This is awkward. Refactor class components. + // updateQueue.capturedValues = null; + derivedStateFromCatch = callGetDerivedStateFromCatch( + ctor, + capturedValues + ); + } + } else { + newState = oldState; } - if (typeof getDerivedStateFromProps === "function") { - applyDerivedStateFromProps( + var derivedStateFromProps = void 0; + if (oldProps !== newProps) { + // The prevState parameter should be the partially updated state. + // Otherwise, spreading state in return values could override updates. + derivedStateFromProps = callGetDerivedStateFromProps( workInProgress, - getDerivedStateFromProps, - newProps + instance, + newProps, + newState ); - newState = workInProgress.memoizedState; + } + + if (derivedStateFromProps !== null && derivedStateFromProps !== undefined) { + // Render-phase updates (like this) should not be added to the update queue, + // So that multiple render passes do not enqueue multiple updates. + // Instead, just synchronously merge the returned state into the instance. + newState = + newState === null || newState === undefined + ? derivedStateFromProps + : Object.assign({}, newState, derivedStateFromProps); + + // Update the base state of the update queue. + // FIXME: This is getting ridiculous. Refactor plz! + var _updateQueue = workInProgress.updateQueue; + if (_updateQueue !== null) { + _updateQueue.baseState = Object.assign( + {}, + _updateQueue.baseState, + derivedStateFromProps + ); + } + } + if (derivedStateFromCatch !== null && derivedStateFromCatch !== undefined) { + // Render-phase updates (like this) should not be added to the update queue, + // So that multiple render passes do not enqueue multiple updates. + // Instead, just synchronously merge the returned state into the instance. + newState = + newState === null || newState === undefined + ? derivedStateFromCatch + : Object.assign({}, newState, derivedStateFromCatch); + + // Update the base state of the update queue. + // FIXME: This is getting ridiculous. Refactor plz! + var _updateQueue2 = workInProgress.updateQueue; + if (_updateQueue2 !== null) { + _updateQueue2.baseState = Object.assign( + {}, + _updateQueue2.baseState, + derivedStateFromCatch + ); + } } if ( @@ -6797,9 +6645,9 @@ var ReactFiberClassComponent = function( } // If shouldComponentUpdate returned false, we should still update the - // memoized state to indicate that this work can be reused. - workInProgress.memoizedProps = newProps; - workInProgress.memoizedState = newState; + // memoized props/state to indicate that this work can be reused. + memoizeProps(workInProgress, newProps); + memoizeState(workInProgress, newState); } // Update the existing instance's state, props, and context pointers even @@ -6815,18 +6663,16 @@ var ReactFiberClassComponent = function( function updateClassInstance(current, workInProgress, renderExpirationTime) { var ctor = workInProgress.type; var instance = workInProgress.stateNode; + resetInputPointers(workInProgress, instance); var oldProps = workInProgress.memoizedProps; var newProps = workInProgress.pendingProps; - instance.props = oldProps; - var oldContext = instance.context; var newUnmaskedContext = getUnmaskedContext(workInProgress); var newContext = getMaskedContext(workInProgress, newUnmaskedContext); - var getDerivedStateFromProps = ctor.getDerivedStateFromProps; var hasNewLifecycles = - typeof getDerivedStateFromProps === "function" || + typeof ctor.getDerivedStateFromProps === "function" || typeof instance.getSnapshotBeforeUpdate === "function"; // Note: During these life-cycles, instance.props/instance.state are what @@ -6850,27 +6696,94 @@ var ReactFiberClassComponent = function( } } + // Compute the next state using the memoized state and the update queue. var oldState = workInProgress.memoizedState; - var newState = (instance.state = oldState); - var updateQueue = workInProgress.updateQueue; - if (updateQueue !== null) { - processUpdateQueue( + // TODO: Previous state can be null. + var newState = void 0; + var derivedStateFromCatch = void 0; + + if (workInProgress.updateQueue !== null) { + newState = processUpdateQueue( + current, workInProgress, - updateQueue, - newProps, + workInProgress.updateQueue, instance, + newProps, renderExpirationTime ); - newState = workInProgress.memoizedState; + + var updateQueue = workInProgress.updateQueue; + if ( + updateQueue !== null && + updateQueue.capturedValues !== null && + enableGetDerivedStateFromCatch && + typeof ctor.getDerivedStateFromCatch === "function" + ) { + var capturedValues = updateQueue.capturedValues; + // Don't remove these from the update queue yet. We need them in + // finishClassComponent. Do the reset there. + // TODO: This is awkward. Refactor class components. + // updateQueue.capturedValues = null; + derivedStateFromCatch = callGetDerivedStateFromCatch( + ctor, + capturedValues + ); + } + } else { + newState = oldState; } - if (typeof getDerivedStateFromProps === "function") { - applyDerivedStateFromProps( + var derivedStateFromProps = void 0; + if (oldProps !== newProps) { + // The prevState parameter should be the partially updated state. + // Otherwise, spreading state in return values could override updates. + derivedStateFromProps = callGetDerivedStateFromProps( workInProgress, - getDerivedStateFromProps, - newProps + instance, + newProps, + newState ); - newState = workInProgress.memoizedState; + } + + if (derivedStateFromProps !== null && derivedStateFromProps !== undefined) { + // Render-phase updates (like this) should not be added to the update queue, + // So that multiple render passes do not enqueue multiple updates. + // Instead, just synchronously merge the returned state into the instance. + newState = + newState === null || newState === undefined + ? derivedStateFromProps + : Object.assign({}, newState, derivedStateFromProps); + + // Update the base state of the update queue. + // FIXME: This is getting ridiculous. Refactor plz! + var _updateQueue3 = workInProgress.updateQueue; + if (_updateQueue3 !== null) { + _updateQueue3.baseState = Object.assign( + {}, + _updateQueue3.baseState, + derivedStateFromProps + ); + } + } + if (derivedStateFromCatch !== null && derivedStateFromCatch !== undefined) { + // Render-phase updates (like this) should not be added to the update queue, + // So that multiple render passes do not enqueue multiple updates. + // Instead, just synchronously merge the returned state into the instance. + newState = + newState === null || newState === undefined + ? derivedStateFromCatch + : Object.assign({}, newState, derivedStateFromCatch); + + // Update the base state of the update queue. + // FIXME: This is getting ridiculous. Refactor plz! + var _updateQueue4 = workInProgress.updateQueue; + if (_updateQueue4 !== null) { + _updateQueue4.baseState = Object.assign( + {}, + _updateQueue4.baseState, + derivedStateFromCatch + ); + } } if ( @@ -6957,8 +6870,8 @@ var ReactFiberClassComponent = function( // If shouldComponentUpdate returned false, we should still update the // memoized props/state to indicate that this work can be reused. - workInProgress.memoizedProps = newProps; - workInProgress.memoizedState = newState; + memoizeProps(workInProgress, newProps); + memoizeState(workInProgress, newState); } // Update the existing instance's state, props, and context pointers even @@ -6972,6 +6885,7 @@ var ReactFiberClassComponent = function( return { adoptClassInstance: adoptClassInstance, + callGetDerivedStateFromProps: callGetDerivedStateFromProps, constructClassInstance: constructClassInstance, mountClassInstance: mountClassInstance, resumeMountClassInstance: resumeMountClassInstance, @@ -6979,7 +6893,7 @@ var ReactFiberClassComponent = function( }; }; -var getCurrentFiberStackAddendum$2 = +var getCurrentFiberStackAddendum$1 = ReactDebugCurrentFiber.getCurrentFiberStackAddendum; var didWarnAboutMaps = void 0; @@ -7018,7 +6932,7 @@ var warnForMissingKey = function(child) {}; "Each child in an array or iterator should have a unique " + '"key" prop. See https://fb.me/react-warning-keys for ' + "more information." + - (getCurrentFiberStackAddendum$2() || ""); + (getCurrentFiberStackAddendum$1() || ""); if (ownerHasKeyUseWarning[currentComponentErrorInfo]) { return; } @@ -7029,7 +6943,7 @@ var warnForMissingKey = function(child) {}; "Each child in an array or iterator should have a unique " + '"key" prop. See https://fb.me/react-warning-keys for ' + "more information.%s", - getCurrentFiberStackAddendum$2() + getCurrentFiberStackAddendum$1() ); }; } @@ -7126,7 +7040,7 @@ function throwOnInvalidObjectType(returnFiber, newChild) { addendum = " If you meant to render a collection of children, use an array " + "instead." + - (getCurrentFiberStackAddendum$2() || ""); + (getCurrentFiberStackAddendum$1() || ""); } invariant( false, @@ -7144,7 +7058,7 @@ function warnOnFunctionType() { "Functions are not valid as a React child. This may happen if " + "you return a Component instead of from render. " + "Or maybe you meant to call this function rather than return it." + - (getCurrentFiberStackAddendum$2() || ""); + (getCurrentFiberStackAddendum$1() || ""); if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) { return; @@ -7156,7 +7070,7 @@ function warnOnFunctionType() { "Functions are not valid as a React child. This may happen if " + "you return a Component instead of from render. " + "Or maybe you meant to call this function rather than return it.%s", - getCurrentFiberStackAddendum$2() || "" + getCurrentFiberStackAddendum$1() || "" ); } @@ -7269,12 +7183,12 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime ); - created.return = returnFiber; + created["return"] = returnFiber; return created; } else { // Update var existing = useFiber(current, textContent, expirationTime); - existing.return = returnFiber; + existing["return"] = returnFiber; return existing; } } @@ -7284,7 +7198,7 @@ function ChildReconciler(shouldTrackSideEffects) { // Move based on index var existing = useFiber(current, element.props, expirationTime); existing.ref = coerceRef(returnFiber, current, element); - existing.return = returnFiber; + existing["return"] = returnFiber; { existing._debugSource = element._source; existing._debugOwner = element._owner; @@ -7298,7 +7212,7 @@ function ChildReconciler(shouldTrackSideEffects) { expirationTime ); created.ref = coerceRef(returnFiber, current, element); - created.return = returnFiber; + created["return"] = returnFiber; return created; } } @@ -7316,12 +7230,12 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime ); - created.return = returnFiber; + created["return"] = returnFiber; return created; } else { // Update var existing = useFiber(current, portal.children || [], expirationTime); - existing.return = returnFiber; + existing["return"] = returnFiber; return existing; } } @@ -7335,12 +7249,12 @@ function ChildReconciler(shouldTrackSideEffects) { expirationTime, key ); - created.return = returnFiber; + created["return"] = returnFiber; return created; } else { // Update var existing = useFiber(current, fragment, expirationTime); - existing.return = returnFiber; + existing["return"] = returnFiber; return existing; } } @@ -7355,7 +7269,7 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime ); - created.return = returnFiber; + created["return"] = returnFiber; return created; } @@ -7368,7 +7282,7 @@ function ChildReconciler(shouldTrackSideEffects) { expirationTime ); _created.ref = coerceRef(returnFiber, null, newChild); - _created.return = returnFiber; + _created["return"] = returnFiber; return _created; } case REACT_PORTAL_TYPE: { @@ -7377,7 +7291,7 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime ); - _created2.return = returnFiber; + _created2["return"] = returnFiber; return _created2; } } @@ -7389,7 +7303,7 @@ function ChildReconciler(shouldTrackSideEffects) { expirationTime, null ); - _created3.return = returnFiber; + _created3["return"] = returnFiber; return _created3; } @@ -7600,7 +7514,7 @@ function ChildReconciler(shouldTrackSideEffects) { "duplicated and/or omitted — the behavior is unsupported and " + "could change in a future version.%s", key, - getCurrentFiberStackAddendum$2() + getCurrentFiberStackAddendum$1() ); break; default: @@ -7745,7 +7659,7 @@ function ChildReconciler(shouldTrackSideEffects) { // current, that means that we reused the fiber. We need to delete // it from the child list so that we don't add it to the deletion // list. - existingChildren.delete( + existingChildren["delete"]( _newFiber2.key === null ? newIdx : _newFiber2.key ); } @@ -7798,7 +7712,7 @@ function ChildReconciler(shouldTrackSideEffects) { "Using Maps as children is unsupported and will likely yield " + "unexpected results. Convert it to a sequence/iterable of keyed " + "ReactElements instead.%s", - getCurrentFiberStackAddendum$2() + getCurrentFiberStackAddendum$1() ) : void 0; didWarnAboutMaps = true; @@ -7924,7 +7838,7 @@ function ChildReconciler(shouldTrackSideEffects) { // current, that means that we reused the fiber. We need to delete // it from the child list so that we don't add it to the deletion // list. - existingChildren.delete( + existingChildren["delete"]( _newFiber4.key === null ? newIdx : _newFiber4.key ); } @@ -7963,7 +7877,7 @@ function ChildReconciler(shouldTrackSideEffects) { // the rest. deleteRemainingChildren(returnFiber, currentFirstChild.sibling); var existing = useFiber(currentFirstChild, textContent, expirationTime); - existing.return = returnFiber; + existing["return"] = returnFiber; return existing; } // The existing first child is not a text node so we need to create one @@ -7974,7 +7888,7 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime ); - created.return = returnFiber; + created["return"] = returnFiber; return created; } @@ -8004,7 +7918,7 @@ function ChildReconciler(shouldTrackSideEffects) { expirationTime ); existing.ref = coerceRef(returnFiber, child, element); - existing.return = returnFiber; + existing["return"] = returnFiber; { existing._debugSource = element._source; existing._debugOwner = element._owner; @@ -8027,7 +7941,7 @@ function ChildReconciler(shouldTrackSideEffects) { expirationTime, element.key ); - created.return = returnFiber; + created["return"] = returnFiber; return created; } else { var _created4 = createFiberFromElement( @@ -8036,7 +7950,7 @@ function ChildReconciler(shouldTrackSideEffects) { expirationTime ); _created4.ref = coerceRef(returnFiber, currentFirstChild, element); - _created4.return = returnFiber; + _created4["return"] = returnFiber; return _created4; } } @@ -8060,7 +7974,7 @@ function ChildReconciler(shouldTrackSideEffects) { ) { deleteRemainingChildren(returnFiber, child.sibling); var existing = useFiber(child, portal.children || [], expirationTime); - existing.return = returnFiber; + existing["return"] = returnFiber; return existing; } else { deleteRemainingChildren(returnFiber, child); @@ -8077,7 +7991,7 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime ); - created.return = returnFiber; + created["return"] = returnFiber; return created; } @@ -8229,7 +8143,7 @@ function cloneChildFibers(current, workInProgress) { ); workInProgress.child = newChild; - newChild.return = workInProgress; + newChild["return"] = workInProgress; while (currentChild.sibling !== null) { currentChild = currentChild.sibling; newChild = newChild.sibling = createWorkInProgress( @@ -8237,14 +8151,11 @@ function cloneChildFibers(current, workInProgress) { currentChild.pendingProps, currentChild.expirationTime ); - newChild.return = workInProgress; + newChild["return"] = workInProgress; } newChild.sibling = null; } -var getCurrentFiberStackAddendum = - ReactDebugCurrentFiber.getCurrentFiberStackAddendum; - var didWarnAboutBadClass = void 0; var didWarnAboutGetDerivedStateOnFunctionalComponent = void 0; var didWarnAboutStatelessRefs = void 0; @@ -8288,6 +8199,8 @@ var ReactFiberBeginWork = function( memoizeState ), adoptClassInstance = _ReactFiberClassCompo.adoptClassInstance, + callGetDerivedStateFromProps = + _ReactFiberClassCompo.callGetDerivedStateFromProps, constructClassInstance = _ReactFiberClassCompo.constructClassInstance, mountClassInstance = _ReactFiberClassCompo.mountClassInstance, resumeMountClassInstance = _ReactFiberClassCompo.resumeMountClassInstance, @@ -8339,20 +8252,9 @@ var ReactFiberBeginWork = function( function updateForwardRef(current, workInProgress) { var render = workInProgress.type.render; - var nextProps = workInProgress.pendingProps; - var ref = workInProgress.ref; - if (hasLegacyContextChanged()) { - // Normally we can bail out on props equality but if context has changed - // we don't do the bailout and we have to reuse existing props instead. - } else if (workInProgress.memoizedProps === nextProps) { - var currentRef = current !== null ? current.ref : null; - if (ref === currentRef) { - return bailoutOnAlreadyFinishedWork(current, workInProgress); - } - } - var nextChildren = render(nextProps, ref); + var nextChildren = render(workInProgress.pendingProps, workInProgress.ref); reconcileChildren(current, workInProgress, nextChildren); - memoizeProps(workInProgress, nextProps); + memoizeProps(workInProgress, nextChildren); return workInProgress.child; } @@ -8438,11 +8340,7 @@ var ReactFiberBeginWork = function( if (current === null) { if (workInProgress.stateNode === null) { // In the initial pass we might need to construct the instance. - constructClassInstance( - workInProgress, - workInProgress.pendingProps, - renderExpirationTime - ); + constructClassInstance(workInProgress, workInProgress.pendingProps); mountClassInstance(workInProgress, renderExpirationTime); shouldUpdate = true; @@ -8460,11 +8358,22 @@ var ReactFiberBeginWork = function( renderExpirationTime ); } + + // We processed the update queue inside updateClassInstance. It may have + // included some errors that were dispatched during the commit phase. + // TODO: Refactor class components so this is less awkward. + var didCaptureError = false; + var updateQueue = workInProgress.updateQueue; + if (updateQueue !== null && updateQueue.capturedValues !== null) { + shouldUpdate = true; + didCaptureError = true; + } return finishClassComponent( current, workInProgress, shouldUpdate, hasContext, + didCaptureError, renderExpirationTime ); } @@ -8474,13 +8383,12 @@ var ReactFiberBeginWork = function( workInProgress, shouldUpdate, hasContext, + didCaptureError, renderExpirationTime ) { // Refs should update even if shouldComponentUpdate returns false markRef(current, workInProgress); - var didCaptureError = (workInProgress.effectTag & DidCapture) !== NoEffect; - if (!shouldUpdate && !didCaptureError) { // Context providers should defer to sCU for rendering if (hasContext) { @@ -8576,26 +8484,29 @@ var ReactFiberBeginWork = function( pushHostRootContext(workInProgress); var updateQueue = workInProgress.updateQueue; if (updateQueue !== null) { - var nextProps = workInProgress.pendingProps; var prevState = workInProgress.memoizedState; - var prevChildren = prevState !== null ? prevState.element : null; - processUpdateQueue( + var state = processUpdateQueue( + current, workInProgress, updateQueue, - nextProps, + null, null, renderExpirationTime ); - var nextState = workInProgress.memoizedState; - // Caution: React DevTools currently depends on this property - // being called "element". - var nextChildren = nextState.element; + memoizeState(workInProgress, state); + updateQueue = workInProgress.updateQueue; - if (nextChildren === prevChildren) { + var element = void 0; + if (updateQueue !== null && updateQueue.capturedValues !== null) { + // There's an uncaught error. Unmount the whole root. + element = null; + } else if (prevState === state) { // If the state is the same as before, that's a bailout because we had // no work that expires at this time. resetHydrationState(); return bailoutOnAlreadyFinishedWork(current, workInProgress); + } else { + element = state.element; } var root = workInProgress.stateNode; if ( @@ -8620,15 +8531,16 @@ var ReactFiberBeginWork = function( workInProgress.child = mountChildFibers( workInProgress, null, - nextChildren, + element, renderExpirationTime ); } else { // Otherwise reset hydration state in case we aborted and resumed another // root. resetHydrationState(); - reconcileChildren(current, workInProgress, nextChildren); + reconcileChildren(current, workInProgress, element); } + memoizeState(workInProgress, state); return workInProgress.child; } resetHydrationState(); @@ -8764,13 +8676,21 @@ var ReactFiberBeginWork = function( workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null; - var getDerivedStateFromProps = Component.getDerivedStateFromProps; - if (typeof getDerivedStateFromProps === "function") { - applyDerivedStateFromProps( + if (typeof Component.getDerivedStateFromProps === "function") { + var partialState = callGetDerivedStateFromProps( workInProgress, - getDerivedStateFromProps, - props + value, + props, + workInProgress.memoizedState ); + + if (partialState !== null && partialState !== undefined) { + workInProgress.memoizedState = Object.assign( + {}, + workInProgress.memoizedState, + partialState + ); + } } // Push context providers early to prevent context stack mismatches. @@ -8784,6 +8704,7 @@ var ReactFiberBeginWork = function( workInProgress, true, hasContext, + false, renderExpirationTime ); } else { @@ -8929,7 +8850,7 @@ var ReactFiberBeginWork = function( var fiber = workInProgress.child; if (fiber !== null) { // Set the return pointer of the child to the work-in-progress fiber. - fiber.return = workInProgress; + fiber["return"] = workInProgress; } while (fiber !== null) { var nextFiber = void 0; @@ -8967,7 +8888,7 @@ var ReactFiberBeginWork = function( // ancestor path already has sufficient priority. break; } - node = node.return; + node = node["return"]; } // Don't scan deeper than a matching consumer. When we render the // consumer, we'll continue scanning from that point. This way the @@ -8989,7 +8910,7 @@ var ReactFiberBeginWork = function( } if (nextFiber !== null) { // Set the return pointer of the child to the work-in-progress fiber. - nextFiber.return = fiber; + nextFiber["return"] = fiber; } else { // No child. Traverse to next sibling. nextFiber = fiber; @@ -9001,13 +8922,11 @@ var ReactFiberBeginWork = function( } var sibling = nextFiber.sibling; if (sibling !== null) { - // Set the return pointer of the sibling to the work-in-progress fiber. - sibling.return = nextFiber.return; nextFiber = sibling; break; } // No more siblings. Traverse up. - nextFiber = nextFiber.return; + nextFiber = nextFiber["return"]; } } fiber = nextFiber; @@ -9024,10 +8943,8 @@ var ReactFiberBeginWork = function( var newProps = workInProgress.pendingProps; var oldProps = workInProgress.memoizedProps; - var canBailOnProps = true; if (hasLegacyContextChanged()) { - canBailOnProps = false; // Normally we can bail out on props equality but if context has changed // we don't do the bailout and we have to reuse existing props instead. } else if (oldProps === newProps) { @@ -9039,20 +8956,6 @@ var ReactFiberBeginWork = function( var newValue = newProps.value; workInProgress.memoizedProps = newProps; - { - var providerPropTypes = workInProgress.type.propTypes; - - if (providerPropTypes) { - checkPropTypes( - providerPropTypes, - newProps, - "prop", - "Context.Provider", - getCurrentFiberStackAddendum - ); - } - } - var changedBits = void 0; if (oldProps === null) { // Initial render @@ -9060,7 +8963,7 @@ var ReactFiberBeginWork = function( } else { if (oldProps.value === newProps.value) { // No change. Bailout early if children are the same. - if (oldProps.children === newProps.children && canBailOnProps) { + if (oldProps.children === newProps.children) { workInProgress.stateNode = 0; pushProvider(workInProgress); return bailoutOnAlreadyFinishedWork(current, workInProgress); @@ -9077,7 +8980,7 @@ var ReactFiberBeginWork = function( (oldValue !== oldValue && newValue !== newValue) // eslint-disable-line no-self-compare ) { // No change. Bailout early if children are the same. - if (oldProps.children === newProps.children && canBailOnProps) { + if (oldProps.children === newProps.children) { workInProgress.stateNode = 0; pushProvider(workInProgress); return bailoutOnAlreadyFinishedWork(current, workInProgress); @@ -9102,7 +9005,7 @@ var ReactFiberBeginWork = function( if (changedBits === 0) { // No change. Bailout early if children are the same. - if (oldProps.children === newProps.children && canBailOnProps) { + if (oldProps.children === newProps.children) { workInProgress.stateNode = 0; pushProvider(workInProgress); return bailoutOnAlreadyFinishedWork(current, workInProgress); @@ -9188,8 +9091,6 @@ var ReactFiberBeginWork = function( } var newChildren = render(newValue); - // React DevTools reads this flag. - workInProgress.effectTag |= PerformedWork; reconcileChildren(current, workInProgress, newChildren); return workInProgress.child; } @@ -9397,7 +9298,7 @@ var ReactFiberCompleteWork = function( function appendAllReturns(returns, workInProgress) { var node = workInProgress.stateNode; if (node) { - node.return = workInProgress; + node["return"] = workInProgress; } while (node !== null) { if ( @@ -9409,17 +9310,17 @@ var ReactFiberCompleteWork = function( } else if (node.tag === ReturnComponent) { returns.push(node.pendingProps.value); } else if (node.child !== null) { - node.child.return = node; + node.child["return"] = node; node = node.child; continue; } while (node.sibling === null) { - if (node.return === null || node.return === workInProgress) { + if (node["return"] === null || node["return"] === workInProgress) { return; } - node = node.return; + node = node["return"]; } - node.sibling.return = node.return; + node.sibling["return"] = node["return"]; node = node.sibling; } } @@ -9475,7 +9376,7 @@ var ReactFiberCompleteWork = function( // down its children. Instead, we'll get insertions from each child in // the portal directly. } else if (node.child !== null) { - node.child.return = node; + node.child["return"] = node; node = node.child; continue; } @@ -9483,12 +9384,12 @@ var ReactFiberCompleteWork = function( return; } while (node.sibling === null) { - if (node.return === null || node.return === workInProgress) { + if (node["return"] === null || node["return"] === workInProgress) { return; } - node = node.return; + node = node["return"]; } - node.sibling.return = node.return; + node.sibling["return"] = node["return"]; node = node.sibling; } } @@ -9555,7 +9456,7 @@ var ReactFiberCompleteWork = function( // down its children. Instead, we'll get insertions from each child in // the portal directly. } else if (node.child !== null) { - node.child.return = node; + node.child["return"] = node; node = node.child; continue; } @@ -9563,12 +9464,12 @@ var ReactFiberCompleteWork = function( return; } while (node.sibling === null) { - if (node.return === null || node.return === workInProgress) { + if (node["return"] === null || node["return"] === workInProgress) { return; } - node = node.return; + node = node["return"]; } - node.sibling.return = node.return; + node.sibling["return"] = node["return"]; node = node.sibling; } }; @@ -9694,6 +9595,20 @@ var ReactFiberCompleteWork = function( case ClassComponent: { // We are leaving this subtree, so pop context if any. popLegacyContextProvider(workInProgress); + + // If this component caught an error, schedule an error log effect. + var instance = workInProgress.stateNode; + var updateQueue = workInProgress.updateQueue; + if (updateQueue !== null && updateQueue.capturedValues !== null) { + workInProgress.effectTag &= ~DidCapture; + if (typeof instance.componentDidCatch === "function") { + workInProgress.effectTag |= ErrLog; + } else { + // Normally we clear this in the commit phase, but since we did not + // schedule an effect, we need to reset it here. + updateQueue.capturedValues = null; + } + } return null; } case HostRoot: { @@ -9713,6 +9628,11 @@ var ReactFiberCompleteWork = function( workInProgress.effectTag &= ~Placement; } updateHostContainer(workInProgress); + + var _updateQueue = workInProgress.updateQueue; + if (_updateQueue !== null && _updateQueue.capturedValues !== null) { + workInProgress.effectTag |= ErrLog; + } return null; } case HostComponent: { @@ -9727,13 +9647,13 @@ var ReactFiberCompleteWork = function( // have newProps so we'll have to reuse them. // TODO: Split the update API as separate for the props vs. children. // Even better would be if children weren't special cased at all tho. - var instance = workInProgress.stateNode; + var _instance = workInProgress.stateNode; var currentHostContext = getHostContext(); // TODO: Experiencing an error where oldProps is null. Suggests a host // component is hitting the resume path. Figure out why. Possibly // related to `hidden`. var updatePayload = prepareUpdate( - instance, + _instance, type, oldProps, newProps, @@ -9787,7 +9707,7 @@ var ReactFiberCompleteWork = function( markUpdate(workInProgress); } } else { - var _instance = createInstance( + var _instance2 = createInstance( type, newProps, rootContainerInstance, @@ -9795,14 +9715,14 @@ var ReactFiberCompleteWork = function( workInProgress ); - appendAllChildren(_instance, workInProgress); + appendAllChildren(_instance2, workInProgress); // Certain renderers require commit-time effects for initial mount. // (eg DOM renderer supports auto-focus for certain elements). // Make sure such renderers get scheduled for later work. if ( finalizeInitialChildren( - _instance, + _instance2, type, newProps, rootContainerInstance, @@ -9811,7 +9731,7 @@ var ReactFiberCompleteWork = function( ) { markUpdate(workInProgress); } - workInProgress.stateNode = _instance; + workInProgress.stateNode = _instance2; } if (workInProgress.ref !== null) { @@ -9918,6 +9838,139 @@ function createCapturedValue(value, source) { }; } +var ReactFiberUnwindWork = function( + hostContext, + legacyContext, + newContext, + scheduleWork, + isAlreadyFailedLegacyErrorBoundary +) { + var popHostContainer = hostContext.popHostContainer, + popHostContext = hostContext.popHostContext; + var popLegacyContextProvider = legacyContext.popContextProvider, + popTopLevelLegacyContextObject = legacyContext.popTopLevelContextObject; + var popProvider = newContext.popProvider; + + function throwException(returnFiber, sourceFiber, rawValue) { + // The source fiber did not complete. + sourceFiber.effectTag |= Incomplete; + // Its effect list is no longer valid. + sourceFiber.firstEffect = sourceFiber.lastEffect = null; + + var value = createCapturedValue(rawValue, sourceFiber); + + var workInProgress = returnFiber; + do { + switch (workInProgress.tag) { + case HostRoot: { + // Uncaught error + var errorInfo = value; + ensureUpdateQueues(workInProgress); + var updateQueue = workInProgress.updateQueue; + updateQueue.capturedValues = [errorInfo]; + workInProgress.effectTag |= ShouldCapture; + return; + } + case ClassComponent: + // Capture and retry + var ctor = workInProgress.type; + var _instance = workInProgress.stateNode; + if ( + (workInProgress.effectTag & DidCapture) === NoEffect && + ((typeof ctor.getDerivedStateFromCatch === "function" && + enableGetDerivedStateFromCatch) || + (_instance !== null && + typeof _instance.componentDidCatch === "function" && + !isAlreadyFailedLegacyErrorBoundary(_instance))) + ) { + ensureUpdateQueues(workInProgress); + var _updateQueue = workInProgress.updateQueue; + var capturedValues = _updateQueue.capturedValues; + if (capturedValues === null) { + _updateQueue.capturedValues = [value]; + } else { + capturedValues.push(value); + } + workInProgress.effectTag |= ShouldCapture; + return; + } + break; + default: + break; + } + workInProgress = workInProgress["return"]; + } while (workInProgress !== null); + } + + function unwindWork(workInProgress) { + switch (workInProgress.tag) { + case ClassComponent: { + popLegacyContextProvider(workInProgress); + var effectTag = workInProgress.effectTag; + if (effectTag & ShouldCapture) { + workInProgress.effectTag = (effectTag & ~ShouldCapture) | DidCapture; + return workInProgress; + } + return null; + } + case HostRoot: { + popHostContainer(workInProgress); + popTopLevelLegacyContextObject(workInProgress); + var _effectTag = workInProgress.effectTag; + if (_effectTag & ShouldCapture) { + workInProgress.effectTag = (_effectTag & ~ShouldCapture) | DidCapture; + return workInProgress; + } + return null; + } + case HostComponent: { + popHostContext(workInProgress); + return null; + } + case HostPortal: + popHostContainer(workInProgress); + return null; + case ContextProvider: + popProvider(workInProgress); + return null; + default: + return null; + } + } + + function unwindInterruptedWork(interruptedWork) { + switch (interruptedWork.tag) { + case ClassComponent: { + popLegacyContextProvider(interruptedWork); + break; + } + case HostRoot: { + popHostContainer(interruptedWork); + popTopLevelLegacyContextObject(interruptedWork); + break; + } + case HostComponent: { + popHostContext(interruptedWork); + break; + } + case HostPortal: + popHostContainer(interruptedWork); + break; + case ContextProvider: + popProvider(interruptedWork); + break; + default: + break; + } + } + + return { + throwException: throwException, + unwindWork: unwindWork, + unwindInterruptedWork: unwindInterruptedWork + }; +}; + // Module provided by RN: /** * Intercept lifecycle errors and ensure they are shown with the correct stack @@ -10203,14 +10256,7 @@ var ReactFiberCommitWork = function( } var updateQueue = finishedWork.updateQueue; if (updateQueue !== null) { - _instance2.props = finishedWork.memoizedProps; - _instance2.state = finishedWork.memoizedState; - commitUpdateQueue( - finishedWork, - updateQueue, - _instance2, - committedExpirationTime - ); + commitCallbacks(updateQueue, _instance2); } return; } @@ -10228,12 +10274,7 @@ var ReactFiberCommitWork = function( break; } } - commitUpdateQueue( - finishedWork, - _updateQueue, - _instance3, - committedExpirationTime - ); + commitCallbacks(_updateQueue, _instance3); } return; } @@ -10270,17 +10311,81 @@ var ReactFiberCommitWork = function( } } + function commitErrorLogging(finishedWork, onUncaughtError) { + switch (finishedWork.tag) { + case ClassComponent: + { + var ctor = finishedWork.type; + var _instance5 = finishedWork.stateNode; + var updateQueue = finishedWork.updateQueue; + invariant( + updateQueue !== null && updateQueue.capturedValues !== null, + "An error logging effect should not have been scheduled if no errors " + + "were captured. This error is likely caused by a bug in React. " + + "Please file an issue." + ); + var capturedErrors = updateQueue.capturedValues; + updateQueue.capturedValues = null; + + if (typeof ctor.getDerivedStateFromCatch !== "function") { + // To preserve the preexisting retry behavior of error boundaries, + // we keep track of which ones already failed during this batch. + // This gets reset before we yield back to the browser. + // TODO: Warn in strict mode if getDerivedStateFromCatch is + // not defined. + markLegacyErrorBoundaryAsFailed(_instance5); + } + + _instance5.props = finishedWork.memoizedProps; + _instance5.state = finishedWork.memoizedState; + for (var i = 0; i < capturedErrors.length; i++) { + var errorInfo = capturedErrors[i]; + var _error = errorInfo.value; + var stack = errorInfo.stack; + logError(finishedWork, errorInfo); + _instance5.componentDidCatch(_error, { + componentStack: stack !== null ? stack : "" + }); + } + } + break; + case HostRoot: { + var _updateQueue2 = finishedWork.updateQueue; + invariant( + _updateQueue2 !== null && _updateQueue2.capturedValues !== null, + "An error logging effect should not have been scheduled if no errors " + + "were captured. This error is likely caused by a bug in React. " + + "Please file an issue." + ); + var _capturedErrors = _updateQueue2.capturedValues; + _updateQueue2.capturedValues = null; + for (var _i = 0; _i < _capturedErrors.length; _i++) { + var _errorInfo = _capturedErrors[_i]; + logError(finishedWork, _errorInfo); + onUncaughtError(_errorInfo.value); + } + break; + } + default: + invariant( + false, + "This unit of work tag cannot capture errors. This error is " + + "likely caused by a bug in React. Please file an issue." + ); + } + } + function commitAttachRef(finishedWork) { var ref = finishedWork.ref; if (ref !== null) { - var _instance5 = finishedWork.stateNode; + var _instance6 = finishedWork.stateNode; var instanceToUse = void 0; switch (finishedWork.tag) { case HostComponent: - instanceToUse = getPublicInstance(_instance5); + instanceToUse = getPublicInstance(_instance6); break; default: - instanceToUse = _instance5; + instanceToUse = _instance6; } if (typeof ref === "function") { ref(instanceToUse); @@ -10324,9 +10429,9 @@ var ReactFiberCommitWork = function( switch (current.tag) { case ClassComponent: { safelyDetachRef(current); - var _instance6 = current.stateNode; - if (typeof _instance6.componentWillUnmount === "function") { - safelyCallComponentWillUnmount(current, _instance6); + var _instance7 = current.stateNode; + if (typeof _instance7.componentWillUnmount === "function") { + safelyCallComponentWillUnmount(current, _instance7); } return; } @@ -10368,7 +10473,7 @@ var ReactFiberCommitWork = function( // If we don't use mutation we drill down into portals here instead. (!mutation || node.tag !== HostPortal) ) { - node.child.return = node; + node.child["return"] = node; node = node.child; continue; } @@ -10376,12 +10481,12 @@ var ReactFiberCommitWork = function( return; } while (node.sibling === null) { - if (node.return === null || node.return === root) { + if (node["return"] === null || node["return"] === root) { return; } - node = node.return; + node = node["return"]; } - node.sibling.return = node.return; + node.sibling["return"] = node["return"]; node = node.sibling; } } @@ -10392,11 +10497,11 @@ var ReactFiberCommitWork = function( // get GC:ed but we don't know which for sure which parent is the current // one so we'll settle for GC:ing the subtree of this child. This child // itself will be GC:ed when the parent updates the next time. - current.return = null; + current["return"] = null; current.child = null; if (current.alternate) { current.alternate.child = null; - current.alternate.return = null; + current.alternate["return"] = null; } } @@ -10464,6 +10569,7 @@ var ReactFiberCommitWork = function( commitLifeCycles: commitLifeCycles, commitBeforeMutationLifeCycles: commitBeforeMutationLifeCycles, + commitErrorLogging: commitErrorLogging, commitAttachRef: commitAttachRef, commitDetachRef: commitDetachRef }; @@ -10485,12 +10591,12 @@ var ReactFiberCommitWork = function( removeChildFromContainer = mutation.removeChildFromContainer; function getHostParentFiber(fiber) { - var parent = fiber.return; + var parent = fiber["return"]; while (parent !== null) { if (isHostParent(parent)) { return parent; } - parent = parent.return; + parent = parent["return"]; } invariant( false, @@ -10515,14 +10621,14 @@ var ReactFiberCommitWork = function( siblings: while (true) { // If we didn't find anything, let's try the next sibling. while (node.sibling === null) { - if (node.return === null || isHostParent(node.return)) { + if (node["return"] === null || isHostParent(node["return"])) { // If we pop out of the root or hit the parent the fiber we are the // last sibling. return null; } - node = node.return; + node = node["return"]; } - node.sibling.return = node.return; + node.sibling["return"] = node["return"]; node = node.sibling; while (node.tag !== HostComponent && node.tag !== HostText) { // If it is not host node and, we might have a host node inside it. @@ -10536,7 +10642,7 @@ var ReactFiberCommitWork = function( if (node.child === null || node.tag === HostPortal) { continue siblings; } else { - node.child.return = node; + node.child["return"] = node; node = node.child; } } @@ -10604,7 +10710,7 @@ var ReactFiberCommitWork = function( // down its children. Instead, we'll get insertions from each child in // the portal directly. } else if (node.child !== null) { - node.child.return = node; + node.child["return"] = node; node = node.child; continue; } @@ -10612,12 +10718,12 @@ var ReactFiberCommitWork = function( return; } while (node.sibling === null) { - if (node.return === null || node.return === finishedWork) { + if (node["return"] === null || node["return"] === finishedWork) { return; } - node = node.return; + node = node["return"]; } - node.sibling.return = node.return; + node.sibling["return"] = node["return"]; node = node.sibling; } } @@ -10634,7 +10740,7 @@ var ReactFiberCommitWork = function( while (true) { if (!currentParentIsValid) { - var parent = node.return; + var parent = node["return"]; findParent: while (true) { invariant( parent !== null, @@ -10655,7 +10761,7 @@ var ReactFiberCommitWork = function( currentParentIsContainer = true; break findParent; } - parent = parent.return; + parent = parent["return"]; } currentParentIsValid = true; } @@ -10676,7 +10782,7 @@ var ReactFiberCommitWork = function( currentParent = node.stateNode.containerInfo; // Visit children because portals might contain host components. if (node.child !== null) { - node.child.return = node; + node.child["return"] = node; node = node.child; continue; } @@ -10684,7 +10790,7 @@ var ReactFiberCommitWork = function( commitUnmount(node); // Visit children because we may find more host components below. if (node.child !== null) { - node.child.return = node; + node.child["return"] = node; node = node.child; continue; } @@ -10693,17 +10799,17 @@ var ReactFiberCommitWork = function( return; } while (node.sibling === null) { - if (node.return === null || node.return === current) { + if (node["return"] === null || node["return"] === current) { return; } - node = node.return; + node = node["return"]; if (node.tag === HostPortal) { // When we go out of the portal, we need to restore the parent. // Since we don't keep a stack of them, we will search for it. currentParentIsValid = false; } } - node.sibling.return = node.return; + node.sibling["return"] = node["return"]; node = node.sibling; } } @@ -10721,8 +10827,8 @@ var ReactFiberCommitWork = function( return; } case HostComponent: { - var _instance7 = finishedWork.stateNode; - if (_instance7 != null) { + var _instance8 = finishedWork.stateNode; + if (_instance8 != null) { // Commit the work prepared earlier. var newProps = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps @@ -10735,7 +10841,7 @@ var ReactFiberCommitWork = function( finishedWork.updateQueue = null; if (updatePayload !== null) { commitUpdate( - _instance7, + _instance8, updatePayload, type, oldProps, @@ -10786,6 +10892,7 @@ var ReactFiberCommitWork = function( commitDeletion: commitDeletion, commitWork: commitWork, commitLifeCycles: commitLifeCycles, + commitErrorLogging: commitErrorLogging, commitAttachRef: commitAttachRef, commitDetachRef: commitDetachRef }; @@ -10794,208 +10901,6 @@ var ReactFiberCommitWork = function( } }; -var ReactFiberUnwindWork = function( - hostContext, - legacyContext, - newContext, - scheduleWork, - markLegacyErrorBoundaryAsFailed, - isAlreadyFailedLegacyErrorBoundary, - onUncaughtError -) { - var popHostContainer = hostContext.popHostContainer, - popHostContext = hostContext.popHostContext; - var popLegacyContextProvider = legacyContext.popContextProvider, - popTopLevelLegacyContextObject = legacyContext.popTopLevelContextObject; - var popProvider = newContext.popProvider; - - function createRootErrorUpdate(fiber, errorInfo, expirationTime) { - var update = createUpdate(expirationTime); - // Unmount the root by rendering null. - update.tag = CaptureUpdate; - // Caution: React DevTools currently depends on this property - // being called "element". - update.payload = { element: null }; - var error = errorInfo.value; - update.callback = function() { - onUncaughtError(error); - logError(fiber, errorInfo); - }; - return update; - } - - function createClassErrorUpdate(fiber, errorInfo, expirationTime) { - var update = createUpdate(expirationTime); - update.tag = CaptureUpdate; - var getDerivedStateFromCatch = fiber.type.getDerivedStateFromCatch; - if ( - enableGetDerivedStateFromCatch && - typeof getDerivedStateFromCatch === "function" - ) { - var _error = errorInfo.value; - update.payload = function() { - return getDerivedStateFromCatch(_error); - }; - } - - var inst = fiber.stateNode; - if (inst !== null && typeof inst.componentDidCatch === "function") { - update.callback = function callback() { - if ( - !enableGetDerivedStateFromCatch || - getDerivedStateFromCatch !== "function" - ) { - // To preserve the preexisting retry behavior of error boundaries, - // we keep track of which ones already failed during this batch. - // This gets reset before we yield back to the browser. - // TODO: Warn in strict mode if getDerivedStateFromCatch is - // not defined. - markLegacyErrorBoundaryAsFailed(this); - } - var error = errorInfo.value; - var stack = errorInfo.stack; - logError(fiber, errorInfo); - this.componentDidCatch(error, { - componentStack: stack !== null ? stack : "" - }); - }; - } - return update; - } - - function throwException( - returnFiber, - sourceFiber, - rawValue, - renderExpirationTime - ) { - // The source fiber did not complete. - sourceFiber.effectTag |= Incomplete; - // Its effect list is no longer valid. - sourceFiber.firstEffect = sourceFiber.lastEffect = null; - - var value = createCapturedValue(rawValue, sourceFiber); - - var workInProgress = returnFiber; - do { - switch (workInProgress.tag) { - case HostRoot: { - var _errorInfo = value; - workInProgress.effectTag |= ShouldCapture; - var update = createRootErrorUpdate( - workInProgress, - _errorInfo, - renderExpirationTime - ); - enqueueCapturedUpdate(workInProgress, update, renderExpirationTime); - return; - } - case ClassComponent: - // Capture and retry - var errorInfo = value; - var ctor = workInProgress.type; - var _instance = workInProgress.stateNode; - if ( - (workInProgress.effectTag & DidCapture) === NoEffect && - ((typeof ctor.getDerivedStateFromCatch === "function" && - enableGetDerivedStateFromCatch) || - (_instance !== null && - typeof _instance.componentDidCatch === "function" && - !isAlreadyFailedLegacyErrorBoundary(_instance))) - ) { - workInProgress.effectTag |= ShouldCapture; - // Schedule the error boundary to re-render using updated state - var _update = createClassErrorUpdate( - workInProgress, - errorInfo, - renderExpirationTime - ); - enqueueCapturedUpdate( - workInProgress, - _update, - renderExpirationTime - ); - return; - } - break; - default: - break; - } - workInProgress = workInProgress.return; - } while (workInProgress !== null); - } - - function unwindWork(workInProgress) { - switch (workInProgress.tag) { - case ClassComponent: { - popLegacyContextProvider(workInProgress); - var effectTag = workInProgress.effectTag; - if (effectTag & ShouldCapture) { - workInProgress.effectTag = (effectTag & ~ShouldCapture) | DidCapture; - return workInProgress; - } - return null; - } - case HostRoot: { - popHostContainer(workInProgress); - popTopLevelLegacyContextObject(workInProgress); - var _effectTag = workInProgress.effectTag; - if (_effectTag & ShouldCapture) { - workInProgress.effectTag = (_effectTag & ~ShouldCapture) | DidCapture; - return workInProgress; - } - return null; - } - case HostComponent: { - popHostContext(workInProgress); - return null; - } - case HostPortal: - popHostContainer(workInProgress); - return null; - case ContextProvider: - popProvider(workInProgress); - return null; - default: - return null; - } - } - - function unwindInterruptedWork(interruptedWork) { - switch (interruptedWork.tag) { - case ClassComponent: { - popLegacyContextProvider(interruptedWork); - break; - } - case HostRoot: { - popHostContainer(interruptedWork); - popTopLevelLegacyContextObject(interruptedWork); - break; - } - case HostComponent: { - popHostContext(interruptedWork); - break; - } - case HostPortal: - popHostContainer(interruptedWork); - break; - case ContextProvider: - popProvider(interruptedWork); - break; - default: - break; - } - } - - return { - throwException: throwException, - unwindWork: unwindWork, - unwindInterruptedWork: unwindInterruptedWork, - createRootErrorUpdate: createRootErrorUpdate, - createClassErrorUpdate: createClassErrorUpdate - }; -}; - var NO_CONTEXT = {}; var ReactFiberHostContext = function(config, stack) { @@ -11180,7 +11085,7 @@ var ReactFiberHydrationContext = function(config) { var childToDelete = createFiberFromHostInstanceForDeletion(); childToDelete.stateNode = instance; - childToDelete.return = returnFiber; + childToDelete["return"] = returnFiber; childToDelete.effectTag = Deletion; // This might seem like it belongs on progressedFirstDeletion. However, @@ -11378,13 +11283,13 @@ var ReactFiberHydrationContext = function(config) { } function popToNextHostParent(fiber) { - var parent = fiber.return; + var parent = fiber["return"]; while ( parent !== null && parent.tag !== HostComponent && parent.tag !== HostRoot ) { - parent = parent.return; + parent = parent["return"]; } hydrationParentFiber = parent; } @@ -11706,7 +11611,7 @@ var ReactFiberLegacyContext = function(stack) { if (isContextProvider(node)) { return node.stateNode.__reactInternalMemoizedMergedChildContext; } - var parent = node.return; + var parent = node["return"]; invariant( parent, "Found unexpected detached subtree parent. " + @@ -11979,15 +11884,11 @@ var ReactFiberScheduler = function(config) { legacyContext, newContext, scheduleWork, - markLegacyErrorBoundaryAsFailed, - isAlreadyFailedLegacyErrorBoundary, - onUncaughtError + isAlreadyFailedLegacyErrorBoundary ), throwException = _ReactFiberUnwindWork.throwException, unwindWork = _ReactFiberUnwindWork.unwindWork, - unwindInterruptedWork = _ReactFiberUnwindWork.unwindInterruptedWork, - createRootErrorUpdate = _ReactFiberUnwindWork.createRootErrorUpdate, - createClassErrorUpdate = _ReactFiberUnwindWork.createClassErrorUpdate; + unwindInterruptedWork = _ReactFiberUnwindWork.unwindInterruptedWork; var _ReactFiberCommitWork = ReactFiberCommitWork( config, @@ -12004,6 +11905,7 @@ var ReactFiberScheduler = function(config) { commitDeletion = _ReactFiberCommitWork.commitDeletion, commitWork = _ReactFiberCommitWork.commitWork, commitLifeCycles = _ReactFiberCommitWork.commitLifeCycles, + commitErrorLogging = _ReactFiberCommitWork.commitErrorLogging, commitAttachRef = _ReactFiberCommitWork.commitAttachRef, commitDetachRef = _ReactFiberCommitWork.commitDetachRef; @@ -12101,10 +12003,10 @@ var ReactFiberScheduler = function(config) { function resetStack() { if (nextUnitOfWork !== null) { - var interruptedWork = nextUnitOfWork.return; + var interruptedWork = nextUnitOfWork["return"]; while (interruptedWork !== null) { unwindInterruptedWork(interruptedWork); - interruptedWork = interruptedWork.return; + interruptedWork = interruptedWork["return"]; } } @@ -12229,6 +12131,10 @@ var ReactFiberScheduler = function(config) { ); } + if (effectTag & ErrLog) { + commitErrorLogging(nextEffect, onUncaughtError); + } + if (effectTag & Ref) { recordEffect(); commitAttachRef(nextEffect); @@ -12435,16 +12341,7 @@ var ReactFiberScheduler = function(config) { } // Check for pending updates. - var newExpirationTime = NoWork; - switch (workInProgress.tag) { - case HostRoot: - case ClassComponent: { - var updateQueue = workInProgress.updateQueue; - if (updateQueue !== null) { - newExpirationTime = updateQueue.expirationTime; - } - } - } + var newExpirationTime = getUpdateExpirationTime(workInProgress); // TODO: Calls need to visit stateNode @@ -12477,7 +12374,7 @@ var ReactFiberScheduler = function(config) { ReactDebugCurrentFiber.setCurrentFiber(workInProgress); } - var returnFiber = workInProgress.return; + var returnFiber = workInProgress["return"]; var siblingFiber = workInProgress.sibling; if ((workInProgress.effectTag & Incomplete) === NoEffect) { @@ -12719,19 +12616,13 @@ var ReactFiberScheduler = function(config) { break; } - { - // Reset global debug state - // We assume this is defined in DEV - resetCurrentlyProcessingQueue(); - } - if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) { var failedUnitOfWork = nextUnitOfWork; replayUnitOfWork(failedUnitOfWork, thrownValue, isAsync); } var sourceFiber = nextUnitOfWork; - var returnFiber = sourceFiber.return; + var returnFiber = sourceFiber["return"]; if (returnFiber === null) { // This is the root. The root could capture its own errors. However, // we don't know if it errors before or after we pushed the host @@ -12743,12 +12634,7 @@ var ReactFiberScheduler = function(config) { onUncaughtError(thrownValue); break; } - throwException( - returnFiber, - sourceFiber, - thrownValue, - nextRenderExpirationTime - ); + throwException(returnFiber, sourceFiber, thrownValue); nextUnitOfWork = completeUnitOfWork(sourceFiber); } break; @@ -12796,13 +12682,31 @@ var ReactFiberScheduler = function(config) { } } + function scheduleCapture(sourceFiber, boundaryFiber, value, expirationTime) { + // TODO: We only support dispatching errors. + var capturedValue = createCapturedValue(value, sourceFiber); + var update = { + expirationTime: expirationTime, + partialState: null, + callback: null, + isReplace: false, + isForced: false, + capturedValue: capturedValue, + next: null + }; + insertUpdateIntoFiber(boundaryFiber, update); + scheduleWork(boundaryFiber, expirationTime); + } + function dispatch(sourceFiber, value, expirationTime) { invariant( !isWorking || isCommitting, "dispatch: Cannot dispatch during the render phase." ); - var fiber = sourceFiber.return; + // TODO: Handle arrays + + var fiber = sourceFiber["return"]; while (fiber !== null) { switch (fiber.tag) { case ClassComponent: @@ -12813,44 +12717,22 @@ var ReactFiberScheduler = function(config) { (typeof instance.componentDidCatch === "function" && !isAlreadyFailedLegacyErrorBoundary(instance)) ) { - var errorInfo = createCapturedValue(value, sourceFiber); - var update = createClassErrorUpdate( - fiber, - errorInfo, - expirationTime - ); - enqueueUpdate(fiber, update, expirationTime); - scheduleWork(fiber, expirationTime); + scheduleCapture(sourceFiber, fiber, value, expirationTime); return; } break; - case HostRoot: { - var _errorInfo = createCapturedValue(value, sourceFiber); - var _update = createRootErrorUpdate( - fiber, - _errorInfo, - expirationTime - ); - enqueueUpdate(fiber, _update, expirationTime); - scheduleWork(fiber, expirationTime); + // TODO: Handle async boundaries + case HostRoot: + scheduleCapture(sourceFiber, fiber, value, expirationTime); return; - } } - fiber = fiber.return; + fiber = fiber["return"]; } if (sourceFiber.tag === HostRoot) { // Error was thrown at the root. There is no parent, so the root // itself should capture it. - var rootFiber = sourceFiber; - var _errorInfo2 = createCapturedValue(value, rootFiber); - var _update2 = createRootErrorUpdate( - rootFiber, - _errorInfo2, - expirationTime - ); - enqueueUpdate(rootFiber, _update2, expirationTime); - scheduleWork(rootFiber, expirationTime); + scheduleCapture(sourceFiber, sourceFiber, value, expirationTime); } } @@ -12978,7 +12860,7 @@ var ReactFiberScheduler = function(config) { node.alternate.expirationTime = expirationTime; } } - if (node.return === null) { + if (node["return"] === null) { if (node.tag === HostRoot) { var root = node.stateNode; if ( @@ -13019,7 +12901,7 @@ var ReactFiberScheduler = function(config) { return; } } - node = node.return; + node = node["return"]; } } @@ -13648,14 +13530,9 @@ var ReactFiberReconciler$1 = function(config) { } } - var update = createUpdate(expirationTime); - // Caution: React DevTools currently depends on this property - // being called "element". - update.payload = { element: element }; - callback = callback === undefined ? null : callback; - if (callback !== null) { - !(typeof callback === "function") + { + !(callback === null || typeof callback === "function") ? warning( false, "render(...): Expected the last optional `callback` argument to be a " + @@ -13663,11 +13540,20 @@ var ReactFiberReconciler$1 = function(config) { callback ) : void 0; - update.callback = callback; } - enqueueUpdate(current, update, expirationTime); + var update = { + expirationTime: expirationTime, + partialState: { element: element }, + callback: callback, + isReplace: false, + isForced: false, + capturedValue: null, + next: null + }; + insertUpdateIntoFiber(current, update); scheduleWork(current, expirationTime); + return expirationTime; } @@ -13845,8 +13731,8 @@ var ReactFiberReconciler$3 = // TODO: decide on the top-level export form. // This is hacky but makes it work with both Rollup and Jest. -var reactReconciler = ReactFiberReconciler$3.default - ? ReactFiberReconciler$3.default +var reactReconciler = ReactFiberReconciler$3["default"] + ? ReactFiberReconciler$3["default"] : ReactFiberReconciler$3; function _classCallCheck$1(instance, Constructor) { @@ -14468,7 +14354,7 @@ var ReactNativeRenderer = { if (root) { // TODO: Is it safe to reset this now or should I wait since this unmount could be deferred? NativeRenderer.updateContainer(null, root, null, function() { - roots.delete(containerTag); + roots["delete"](containerTag); }); } }, @@ -14535,8 +14421,8 @@ var ReactNativeRenderer$3 = // TODO: decide on the top-level export form. // This is hacky but makes it work with both Rollup and Jest. -var reactNativeRenderer = ReactNativeRenderer$3.default - ? ReactNativeRenderer$3.default +var reactNativeRenderer = ReactNativeRenderer$3["default"] + ? ReactNativeRenderer$3["default"] : ReactNativeRenderer$3; module.exports = reactNativeRenderer; diff --git a/Libraries/Renderer/oss/ReactNativeRenderer-prod.js b/Libraries/Renderer/oss/ReactNativeRenderer-prod.js index 09031ec3a6c..f7eb9e09f0d 100644 --- a/Libraries/Renderer/oss/ReactNativeRenderer-prod.js +++ b/Libraries/Renderer/oss/ReactNativeRenderer-prod.js @@ -5,7 +5,6 @@ * LICENSE file in the root directory of this source tree. * * @noflow - * @providesModule ReactNativeRenderer-prod * @preventMunge */ @@ -307,7 +306,7 @@ function getListener(inst, registrationName) { return listener; } function getParent(inst) { - do inst = inst.return; + do inst = inst["return"]; while (inst && 5 !== inst.tag); return inst ? inst : null; } @@ -1123,17 +1122,21 @@ var ReactNativeEventEmitter = Object.freeze({ } }); RCTEventEmitter.register(ReactNativeEventEmitter); -var hasSymbol = "function" === typeof Symbol && Symbol.for, - REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for("react.element") : 60103, - REACT_CALL_TYPE = hasSymbol ? Symbol.for("react.call") : 60104, - REACT_RETURN_TYPE = hasSymbol ? Symbol.for("react.return") : 60105, - REACT_PORTAL_TYPE = hasSymbol ? Symbol.for("react.portal") : 60106, - REACT_FRAGMENT_TYPE = hasSymbol ? Symbol.for("react.fragment") : 60107, - REACT_STRICT_MODE_TYPE = hasSymbol ? Symbol.for("react.strict_mode") : 60108, - REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for("react.provider") : 60109, - REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for("react.context") : 60110, - REACT_ASYNC_MODE_TYPE = hasSymbol ? Symbol.for("react.async_mode") : 60111, - REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for("react.forward_ref") : 60112, +var hasSymbol = "function" === typeof Symbol && Symbol["for"], + REACT_ELEMENT_TYPE = hasSymbol ? Symbol["for"]("react.element") : 60103, + REACT_CALL_TYPE = hasSymbol ? Symbol["for"]("react.call") : 60104, + REACT_RETURN_TYPE = hasSymbol ? Symbol["for"]("react.return") : 60105, + REACT_PORTAL_TYPE = hasSymbol ? Symbol["for"]("react.portal") : 60106, + REACT_FRAGMENT_TYPE = hasSymbol ? Symbol["for"]("react.fragment") : 60107, + REACT_STRICT_MODE_TYPE = hasSymbol + ? Symbol["for"]("react.strict_mode") + : 60108, + REACT_PROVIDER_TYPE = hasSymbol ? Symbol["for"]("react.provider") : 60109, + REACT_CONTEXT_TYPE = hasSymbol ? Symbol["for"]("react.context") : 60110, + REACT_ASYNC_MODE_TYPE = hasSymbol ? Symbol["for"]("react.async_mode") : 60111, + REACT_FORWARD_REF_TYPE = hasSymbol + ? Symbol["for"]("react.forward_ref") + : 60112, MAYBE_ITERATOR_SYMBOL = "function" === typeof Symbol && Symbol.iterator; function getIteratorFn(maybeIterable) { if (null === maybeIterable || "undefined" === typeof maybeIterable) @@ -1207,7 +1210,7 @@ function getStackAddendumByWorkInProgressFiber(workInProgress) { JSCompiler_inline_result = ""; } info += JSCompiler_inline_result; - workInProgress = workInProgress.return; + workInProgress = workInProgress["return"]; } while (workInProgress); return info; } @@ -1466,11 +1469,11 @@ var ReactCurrentOwner = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner; function isFiberMountedImpl(fiber) { var node = fiber; - if (fiber.alternate) for (; node.return; ) node = node.return; + if (fiber.alternate) for (; node["return"]; ) node = node["return"]; else { if (0 !== (node.effectTag & 2)) return 1; - for (; node.return; ) - if (((node = node.return), 0 !== (node.effectTag & 2))) return 1; + for (; node["return"]; ) + if (((node = node["return"]), 0 !== (node.effectTag & 2))) return 1; } return 3 === node.tag ? 2 : 3; } @@ -1497,7 +1500,7 @@ function findCurrentFiberUsingSlowPath(fiber) { 1 === alternate ? null : fiber ); for (var a = fiber, b = alternate; ; ) { - var parentA = a.return, + var parentA = a["return"], parentB = parentA ? parentA.alternate : null; if (!parentA || !parentB) break; if (parentA.child === parentB.child) { @@ -1508,7 +1511,7 @@ function findCurrentFiberUsingSlowPath(fiber) { } invariant(!1, "Unable to find node on an unmounted component."); } - if (a.return !== b.return) (a = parentA), (b = parentB); + if (a["return"] !== b["return"]) (a = parentA), (b = parentB); else { child = !1; for (var _child = parentA.child; _child; ) { @@ -1561,14 +1564,14 @@ function findCurrentHostFiber(parent) { if (!parent) return null; for (var node = parent; ; ) { if (5 === node.tag || 6 === node.tag) return node; - if (node.child) (node.child.return = node), (node = node.child); + if (node.child) (node.child["return"] = node), (node = node.child); else { if (node === parent) break; for (; !node.sibling; ) { - if (!node.return || node.return === parent) return null; - node = node.return; + if (!node["return"] || node["return"] === parent) return null; + node = node["return"]; } - node.sibling.return = node.return; + node.sibling["return"] = node["return"]; node = node.sibling; } } @@ -1580,14 +1583,14 @@ function findCurrentHostFiberWithNoPortals(parent) { for (var node = parent; ; ) { if (5 === node.tag || 6 === node.tag) return node; if (node.child && 4 !== node.tag) - (node.child.return = node), (node = node.child); + (node.child["return"] = node), (node = node.child); else { if (node === parent) break; for (; !node.sibling; ) { - if (!node.return || node.return === parent) return null; - node = node.return; + if (!node["return"] || node["return"] === parent) return null; + node = node["return"]; } - node.sibling.return = node.return; + node.sibling["return"] = node["return"]; node = node.sibling; } } @@ -1596,7 +1599,8 @@ function findCurrentHostFiberWithNoPortals(parent) { function FiberNode(tag, pendingProps, key, mode) { this.tag = tag; this.key = key; - this.sibling = this.child = this.return = this.stateNode = this.type = null; + this.stateNode = this.type = null; + this.sibling = this.child = this["return"] = null; this.index = 0; this.ref = null; this.pendingProps = pendingProps; @@ -1761,282 +1765,164 @@ function onCommitUnmount(fiber) { new Set(); function createUpdateQueue(baseState) { return { - expirationTime: 0, baseState: baseState, - firstUpdate: null, - lastUpdate: null, - firstCapturedUpdate: null, - lastCapturedUpdate: null, - firstEffect: null, - lastEffect: null, - firstCapturedEffect: null, - lastCapturedEffect: null, - hasForceUpdate: !1 - }; -} -function cloneUpdateQueue(currentQueue) { - return { - expirationTime: currentQueue.expirationTime, - baseState: currentQueue.baseState, - firstUpdate: currentQueue.firstUpdate, - lastUpdate: currentQueue.lastUpdate, - firstCapturedUpdate: null, - lastCapturedUpdate: null, + expirationTime: 0, + first: null, + last: null, + callbackList: null, hasForceUpdate: !1, - firstEffect: null, - lastEffect: null, - firstCapturedEffect: null, - lastCapturedEffect: null + isInitialized: !1, + capturedValues: null }; } -function createUpdate(expirationTime) { - return { - expirationTime: expirationTime, - tag: 0, - payload: null, - callback: null, - next: null, - nextEffect: null - }; -} -function appendUpdateToQueue(queue, update, expirationTime) { - null === queue.lastUpdate - ? (queue.firstUpdate = queue.lastUpdate = update) - : ((queue.lastUpdate.next = update), (queue.lastUpdate = update)); - if (0 === queue.expirationTime || queue.expirationTime > expirationTime) - queue.expirationTime = expirationTime; -} -function enqueueUpdate(fiber, update, expirationTime) { - var alternate = fiber.alternate; - if (null === alternate) { - var queue1 = fiber.updateQueue; - var queue2 = null; - null === queue1 && - (queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState)); - } else - (queue1 = fiber.updateQueue), - (queue2 = alternate.updateQueue), - null === queue1 - ? null === queue2 - ? ((queue1 = fiber.updateQueue = createUpdateQueue( - fiber.memoizedState - )), - (queue2 = alternate.updateQueue = createUpdateQueue( - alternate.memoizedState - ))) - : (queue1 = fiber.updateQueue = cloneUpdateQueue(queue2)) - : null === queue2 && - (queue2 = alternate.updateQueue = cloneUpdateQueue(queue1)); - null === queue2 || queue1 === queue2 - ? appendUpdateToQueue(queue1, update, expirationTime) - : null === queue1.lastUpdate || null === queue2.lastUpdate - ? (appendUpdateToQueue(queue1, update, expirationTime), - appendUpdateToQueue(queue2, update, expirationTime)) - : (appendUpdateToQueue(queue1, update, expirationTime), - (queue2.lastUpdate = update)); -} -function enqueueCapturedUpdate(workInProgress, update, renderExpirationTime) { - var workInProgressQueue = workInProgress.updateQueue; - workInProgressQueue = - null === workInProgressQueue - ? (workInProgress.updateQueue = createUpdateQueue( - workInProgress.memoizedState - )) - : ensureWorkInProgressQueueIsAClone(workInProgress, workInProgressQueue); - null === workInProgressQueue.lastCapturedUpdate - ? (workInProgressQueue.firstCapturedUpdate = workInProgressQueue.lastCapturedUpdate = update) - : ((workInProgressQueue.lastCapturedUpdate.next = update), - (workInProgressQueue.lastCapturedUpdate = update)); +function insertUpdateIntoQueue(queue, update) { + null === queue.last + ? (queue.first = queue.last = update) + : ((queue.last.next = update), (queue.last = update)); if ( - 0 === workInProgressQueue.expirationTime || - workInProgressQueue.expirationTime > renderExpirationTime + 0 === queue.expirationTime || + queue.expirationTime > update.expirationTime ) - workInProgressQueue.expirationTime = renderExpirationTime; + queue.expirationTime = update.expirationTime; } -function ensureWorkInProgressQueueIsAClone(workInProgress, queue) { - var current = workInProgress.alternate; - null !== current && - queue === current.updateQueue && - (queue = workInProgress.updateQueue = cloneUpdateQueue(queue)); - return queue; +var q1 = void 0, + q2 = void 0; +function ensureUpdateQueues(fiber) { + q1 = q2 = null; + var alternateFiber = fiber.alternate, + queue1 = fiber.updateQueue; + null === queue1 && (queue1 = fiber.updateQueue = createUpdateQueue(null)); + null !== alternateFiber + ? ((fiber = alternateFiber.updateQueue), + null === fiber && + (fiber = alternateFiber.updateQueue = createUpdateQueue(null))) + : (fiber = null); + q1 = queue1; + q2 = fiber !== queue1 ? fiber : null; } -function getStateFromUpdate( - workInProgress, - queue, - update, - prevState, - nextProps, - instance -) { - switch (update.tag) { - case 1: - return ( - (workInProgress = update.payload), - "function" === typeof workInProgress - ? workInProgress.call(instance, prevState, nextProps) - : workInProgress - ); - case 3: - workInProgress.effectTag = (workInProgress.effectTag & -1025) | 64; - case 0: - workInProgress = update.payload; - nextProps = - "function" === typeof workInProgress - ? workInProgress.call(instance, prevState, nextProps) - : workInProgress; - if (null === nextProps || void 0 === nextProps) break; - return Object.assign({}, prevState, nextProps); - case 2: - queue.hasForceUpdate = !0; - } - return prevState; +function insertUpdateIntoFiber(fiber, update) { + ensureUpdateQueues(fiber); + fiber = q1; + var queue2 = q2; + null === queue2 + ? insertUpdateIntoQueue(fiber, update) + : null === fiber.last || null === queue2.last + ? (insertUpdateIntoQueue(fiber, update), + insertUpdateIntoQueue(queue2, update)) + : (insertUpdateIntoQueue(fiber, update), (queue2.last = update)); +} +function getStateFromUpdate(update, instance, prevState, props) { + update = update.partialState; + return "function" === typeof update + ? update.call(instance, prevState, props) + : update; } function processUpdateQueue( + current, workInProgress, queue, - props, instance, + props, renderExpirationTime ) { - if ( - !(0 === queue.expirationTime || queue.expirationTime > renderExpirationTime) + null !== current && + current.updateQueue === queue && + (queue = workInProgress.updateQueue = { + baseState: queue.baseState, + expirationTime: queue.expirationTime, + first: queue.first, + last: queue.last, + isInitialized: queue.isInitialized, + capturedValues: queue.capturedValues, + callbackList: null, + hasForceUpdate: !1 + }); + queue.expirationTime = 0; + queue.isInitialized + ? (current = queue.baseState) + : ((current = queue.baseState = workInProgress.memoizedState), + (queue.isInitialized = !0)); + for ( + var dontMutatePrevState = !0, update = queue.first, didSkip = !1; + null !== update; + ) { - queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue); + var updateExpirationTime = update.expirationTime; + if (updateExpirationTime > renderExpirationTime) { + var remainingExpirationTime = queue.expirationTime; + if ( + 0 === remainingExpirationTime || + remainingExpirationTime > updateExpirationTime + ) + queue.expirationTime = updateExpirationTime; + didSkip || ((didSkip = !0), (queue.baseState = current)); + } else { + didSkip || + ((queue.first = update.next), + null === queue.first && (queue.last = null)); + if (update.isReplace) + (current = getStateFromUpdate(update, instance, current, props)), + (dontMutatePrevState = !0); + else if ( + (updateExpirationTime = getStateFromUpdate( + update, + instance, + current, + props + )) + ) + (current = dontMutatePrevState + ? Object.assign({}, current, updateExpirationTime) + : Object.assign(current, updateExpirationTime)), + (dontMutatePrevState = !1); + update.isForced && (queue.hasForceUpdate = !0); + null !== update.callback && + ((updateExpirationTime = queue.callbackList), + null === updateExpirationTime && + (updateExpirationTime = queue.callbackList = []), + updateExpirationTime.push(update)); + null !== update.capturedValue && + ((updateExpirationTime = queue.capturedValues), + null === updateExpirationTime + ? (queue.capturedValues = [update.capturedValue]) + : updateExpirationTime.push(update.capturedValue)); + } + update = update.next; + } + null !== queue.callbackList + ? (workInProgress.effectTag |= 32) + : null !== queue.first || + queue.hasForceUpdate || + null !== queue.capturedValues || + (workInProgress.updateQueue = null); + didSkip || (queue.baseState = current); + return current; +} +function commitCallbacks(queue, context) { + var callbackList = queue.callbackList; + if (null !== callbackList) for ( - var newBaseState = queue.baseState, - newFirstUpdate = null, - newExpirationTime = 0, - update = queue.firstUpdate, - resultState = newBaseState; - null !== update; - + queue.callbackList = null, queue = 0; + queue < callbackList.length; + queue++ ) { - var updateExpirationTime = update.expirationTime; - if (updateExpirationTime > renderExpirationTime) { - if ( - (null === newFirstUpdate && - ((newFirstUpdate = update), (newBaseState = resultState)), - 0 === newExpirationTime || newExpirationTime > updateExpirationTime) - ) - newExpirationTime = updateExpirationTime; - } else - (resultState = getStateFromUpdate( - workInProgress, - queue, - update, - resultState, - props, - instance - )), - null !== update.callback && - ((workInProgress.effectTag |= 32), - (update.nextEffect = null), - null === queue.lastEffect - ? (queue.firstEffect = queue.lastEffect = update) - : ((queue.lastEffect.nextEffect = update), - (queue.lastEffect = update))); - update = update.next; + var update = callbackList[queue], + _callback = update.callback; + update.callback = null; + invariant( + "function" === typeof _callback, + "Invalid argument passed as callback. Expected a function. Instead received: %s", + _callback + ); + _callback.call(context); } - updateExpirationTime = null; - for (update = queue.firstCapturedUpdate; null !== update; ) { - var _updateExpirationTime = update.expirationTime; - if (_updateExpirationTime > renderExpirationTime) { - if ( - (null === updateExpirationTime && - ((updateExpirationTime = update), - null === newFirstUpdate && (newBaseState = resultState)), - 0 === newExpirationTime || newExpirationTime > _updateExpirationTime) - ) - newExpirationTime = _updateExpirationTime; - } else - (resultState = getStateFromUpdate( - workInProgress, - queue, - update, - resultState, - props, - instance - )), - null !== update.callback && - ((workInProgress.effectTag |= 32), - (update.nextEffect = null), - null === queue.lastCapturedEffect - ? (queue.firstCapturedEffect = queue.lastCapturedEffect = update) - : ((queue.lastCapturedEffect.nextEffect = update), - (queue.lastCapturedEffect = update))); - update = update.next; - } - null === newFirstUpdate && (queue.lastUpdate = null); - null === updateExpirationTime - ? (queue.lastCapturedUpdate = null) - : (workInProgress.effectTag |= 32); - null === newFirstUpdate && - null === updateExpirationTime && - (newBaseState = resultState); - queue.baseState = newBaseState; - queue.firstUpdate = newFirstUpdate; - queue.firstCapturedUpdate = updateExpirationTime; - queue.expirationTime = newExpirationTime; - workInProgress.memoizedState = resultState; - } -} -function callCallback(callback, context) { - invariant( - "function" === typeof callback, - "Invalid argument passed as callback. Expected a function. Instead received: %s", - callback - ); - callback.call(context); -} -function commitUpdateQueue(finishedWork, finishedQueue, instance) { - null !== finishedQueue.firstCapturedUpdate && - (null !== finishedQueue.lastUpdate && - ((finishedQueue.lastUpdate.next = finishedQueue.firstCapturedUpdate), - (finishedQueue.lastUpdate = finishedQueue.lastCapturedUpdate)), - (finishedQueue.firstCapturedUpdate = finishedQueue.lastCapturedUpdate = null)); - finishedWork = finishedQueue.firstEffect; - for ( - finishedQueue.firstEffect = finishedQueue.lastEffect = null; - null !== finishedWork; - - ) { - var _callback3 = finishedWork.callback; - null !== _callback3 && - ((finishedWork.callback = null), callCallback(_callback3, instance)); - finishedWork = finishedWork.nextEffect; - } - finishedWork = finishedQueue.firstCapturedEffect; - for ( - finishedQueue.firstCapturedEffect = finishedQueue.lastCapturedEffect = null; - null !== finishedWork; - - ) - (finishedQueue = finishedWork.callback), - null !== finishedQueue && - ((finishedWork.callback = null), callCallback(finishedQueue, instance)), - (finishedWork = finishedWork.nextEffect); -} -function applyDerivedStateFromProps( - workInProgress, - getDerivedStateFromProps, - nextProps -) { - var prevState = workInProgress.memoizedState; - getDerivedStateFromProps = getDerivedStateFromProps(nextProps, prevState); - prevState = - null === getDerivedStateFromProps || void 0 === getDerivedStateFromProps - ? prevState - : Object.assign({}, prevState, getDerivedStateFromProps); - workInProgress.memoizedState = prevState; - workInProgress = workInProgress.updateQueue; - null !== workInProgress && - 0 === workInProgress.expirationTime && - (workInProgress.baseState = prevState); } function ReactFiberClassComponent( legacyContext, scheduleWork, - computeExpirationForFiber + computeExpirationForFiber, + memoizeProps, + memoizeState ) { function checkShouldComponentUpdate( workInProgress, @@ -2047,8 +1933,9 @@ function ReactFiberClassComponent( newContext ) { if ( - null !== workInProgress.updateQueue && - workInProgress.updateQueue.hasForceUpdate + null === oldProps || + (null !== workInProgress.updateQueue && + workInProgress.updateQueue.hasForceUpdate) ) return !0; var instance = workInProgress.stateNode; @@ -2061,7 +1948,7 @@ function ReactFiberClassComponent( : !0; } function adoptClassInstance(workInProgress, instance) { - instance.updater = classComponentUpdater; + instance.updater = updater; workInProgress.stateNode = instance; instance._reactInternalFiber = workInProgress; } @@ -2077,52 +1964,78 @@ function ReactFiberClassComponent( "function" === typeof instance.UNSAFE_componentWillReceiveProps && instance.UNSAFE_componentWillReceiveProps(newProps, newContext); instance.state !== workInProgress && - classComponentUpdater.enqueueReplaceState(instance, instance.state, null); + updater.enqueueReplaceState(instance, instance.state, null); + } + function callGetDerivedStateFromProps( + workInProgress, + instance, + nextProps, + prevState + ) { + workInProgress = workInProgress.type; + if ("function" === typeof workInProgress.getDerivedStateFromProps) + return workInProgress.getDerivedStateFromProps.call( + null, + nextProps, + prevState + ); } var cacheContext = legacyContext.cacheContext, getMaskedContext = legacyContext.getMaskedContext, getUnmaskedContext = legacyContext.getUnmaskedContext, isContextConsumer = legacyContext.isContextConsumer, hasContextChanged = legacyContext.hasContextChanged, - classComponentUpdater = { + updater = { isMounted: isMounted, - enqueueSetState: function(inst, payload, callback) { - inst = inst._reactInternalFiber; - var expirationTime = computeExpirationForFiber(inst), - update = createUpdate(expirationTime); - update.payload = payload; - void 0 !== callback && - null !== callback && - (update.callback = callback); - enqueueUpdate(inst, update, expirationTime); - scheduleWork(inst, expirationTime); + enqueueSetState: function(instance, partialState, callback) { + instance = instance._reactInternalFiber; + callback = void 0 === callback ? null : callback; + var expirationTime = computeExpirationForFiber(instance); + insertUpdateIntoFiber(instance, { + expirationTime: expirationTime, + partialState: partialState, + callback: callback, + isReplace: !1, + isForced: !1, + capturedValue: null, + next: null + }); + scheduleWork(instance, expirationTime); }, - enqueueReplaceState: function(inst, payload, callback) { - inst = inst._reactInternalFiber; - var expirationTime = computeExpirationForFiber(inst), - update = createUpdate(expirationTime); - update.tag = 1; - update.payload = payload; - void 0 !== callback && - null !== callback && - (update.callback = callback); - enqueueUpdate(inst, update, expirationTime); - scheduleWork(inst, expirationTime); + enqueueReplaceState: function(instance, state, callback) { + instance = instance._reactInternalFiber; + callback = void 0 === callback ? null : callback; + var expirationTime = computeExpirationForFiber(instance); + insertUpdateIntoFiber(instance, { + expirationTime: expirationTime, + partialState: state, + callback: callback, + isReplace: !0, + isForced: !1, + capturedValue: null, + next: null + }); + scheduleWork(instance, expirationTime); }, - enqueueForceUpdate: function(inst, callback) { - inst = inst._reactInternalFiber; - var expirationTime = computeExpirationForFiber(inst), - update = createUpdate(expirationTime); - update.tag = 2; - void 0 !== callback && - null !== callback && - (update.callback = callback); - enqueueUpdate(inst, update, expirationTime); - scheduleWork(inst, expirationTime); + enqueueForceUpdate: function(instance, callback) { + instance = instance._reactInternalFiber; + callback = void 0 === callback ? null : callback; + var expirationTime = computeExpirationForFiber(instance); + insertUpdateIntoFiber(instance, { + expirationTime: expirationTime, + partialState: null, + callback: callback, + isReplace: !1, + isForced: !0, + capturedValue: null, + next: null + }); + scheduleWork(instance, expirationTime); } }; return { adoptClassInstance: adoptClassInstance, + callGetDerivedStateFromProps: callGetDerivedStateFromProps, constructClassInstance: function(workInProgress, props) { var ctor = workInProgress.type, unmaskedContext = getUnmaskedContext(workInProgress), @@ -2130,15 +2043,25 @@ function ReactFiberClassComponent( context = needsContext ? getMaskedContext(workInProgress, unmaskedContext) : emptyObject; - props = new ctor(props, context); - workInProgress.memoizedState = - null !== props.state && void 0 !== props.state ? props.state : null; - adoptClassInstance(workInProgress, props); + ctor = new ctor(props, context); + var state = + null !== ctor.state && void 0 !== ctor.state ? ctor.state : null; + adoptClassInstance(workInProgress, ctor); + workInProgress.memoizedState = state; + props = callGetDerivedStateFromProps(workInProgress, ctor, props, state); + null !== props && + void 0 !== props && + (workInProgress.memoizedState = Object.assign( + {}, + workInProgress.memoizedState, + props + )); needsContext && cacheContext(workInProgress, unmaskedContext, context); - return props; + return ctor; }, mountClassInstance: function(workInProgress, renderExpirationTime) { var ctor = workInProgress.type, + current = workInProgress.alternate, instance = workInProgress.stateNode, props = workInProgress.pendingProps, unmaskedContext = getUnmaskedContext(workInProgress); @@ -2146,20 +2069,6 @@ function ReactFiberClassComponent( instance.state = workInProgress.memoizedState; instance.refs = emptyObject; instance.context = getMaskedContext(workInProgress, unmaskedContext); - unmaskedContext = workInProgress.updateQueue; - null !== unmaskedContext && - (processUpdateQueue( - workInProgress, - unmaskedContext, - props, - instance, - renderExpirationTime - ), - (instance.state = workInProgress.memoizedState)); - unmaskedContext = workInProgress.type.getDerivedStateFromProps; - "function" === typeof unmaskedContext && - (applyDerivedStateFromProps(workInProgress, unmaskedContext, props), - (instance.state = workInProgress.memoizedState)); "function" === typeof ctor.getDerivedStateFromProps || "function" === typeof instance.getSnapshotBeforeUpdate || ("function" !== typeof instance.UNSAFE_componentWillMount && @@ -2170,36 +2079,32 @@ function ReactFiberClassComponent( "function" === typeof instance.UNSAFE_componentWillMount && instance.UNSAFE_componentWillMount(), ctor !== instance.state && - classComponentUpdater.enqueueReplaceState( - instance, - instance.state, - null - ), - (unmaskedContext = workInProgress.updateQueue), - null !== unmaskedContext && - (processUpdateQueue( + updater.enqueueReplaceState(instance, instance.state, null), + (ctor = workInProgress.updateQueue), + null !== ctor && + (instance.state = processUpdateQueue( + current, workInProgress, - unmaskedContext, - props, + ctor, instance, + props, renderExpirationTime - ), - (instance.state = workInProgress.memoizedState))); + ))); "function" === typeof instance.componentDidMount && (workInProgress.effectTag |= 4); }, resumeMountClassInstance: function(workInProgress, renderExpirationTime) { var ctor = workInProgress.type, - instance = workInProgress.stateNode, - oldProps = workInProgress.memoizedProps, - newProps = workInProgress.pendingProps; - instance.props = oldProps; - var oldContext = instance.context, + instance = workInProgress.stateNode; + instance.props = workInProgress.memoizedProps; + instance.state = workInProgress.memoizedState; + var oldProps = workInProgress.memoizedProps, + newProps = workInProgress.pendingProps, + oldContext = instance.context, newUnmaskedContext = getUnmaskedContext(workInProgress); newUnmaskedContext = getMaskedContext(workInProgress, newUnmaskedContext); - var getDerivedStateFromProps = ctor.getDerivedStateFromProps; (ctor = - "function" === typeof getDerivedStateFromProps || + "function" === typeof ctor.getDerivedStateFromProps || "function" === typeof instance.getSnapshotBeforeUpdate) || ("function" !== typeof instance.UNSAFE_componentWillReceiveProps && "function" !== typeof instance.componentWillReceiveProps) || @@ -2210,29 +2115,43 @@ function ReactFiberClassComponent( newProps, newUnmaskedContext )); - var oldState = workInProgress.memoizedState; - oldContext = instance.state = oldState; - var updateQueue = workInProgress.updateQueue; - null !== updateQueue && - (processUpdateQueue( + oldContext = workInProgress.memoizedState; + renderExpirationTime = + null !== workInProgress.updateQueue + ? processUpdateQueue( + null, + workInProgress, + workInProgress.updateQueue, + instance, + newProps, + renderExpirationTime + ) + : oldContext; + var derivedStateFromProps = void 0; + oldProps !== newProps && + (derivedStateFromProps = callGetDerivedStateFromProps( workInProgress, - updateQueue, - newProps, instance, + newProps, renderExpirationTime - ), - (oldContext = workInProgress.memoizedState)); - "function" === typeof getDerivedStateFromProps && - (applyDerivedStateFromProps( - workInProgress, - getDerivedStateFromProps, - newProps - ), - (oldContext = workInProgress.memoizedState)); + )); + if (null !== derivedStateFromProps && void 0 !== derivedStateFromProps) { + renderExpirationTime = + null === renderExpirationTime || void 0 === renderExpirationTime + ? derivedStateFromProps + : Object.assign({}, renderExpirationTime, derivedStateFromProps); + var _updateQueue = workInProgress.updateQueue; + null !== _updateQueue && + (_updateQueue.baseState = Object.assign( + {}, + _updateQueue.baseState, + derivedStateFromProps + )); + } if ( !( oldProps !== newProps || - oldState !== oldContext || + oldContext !== renderExpirationTime || hasContextChanged() || (null !== workInProgress.updateQueue && workInProgress.updateQueue.hasForceUpdate) @@ -2243,12 +2162,12 @@ function ReactFiberClassComponent( (workInProgress.effectTag |= 4), !1 ); - (renderExpirationTime = checkShouldComponentUpdate( + (oldProps = checkShouldComponentUpdate( workInProgress, oldProps, newProps, - oldState, oldContext, + renderExpirationTime, newUnmaskedContext )) ? (ctor || @@ -2262,12 +2181,12 @@ function ReactFiberClassComponent( (workInProgress.effectTag |= 4)) : ("function" === typeof instance.componentDidMount && (workInProgress.effectTag |= 4), - (workInProgress.memoizedProps = newProps), - (workInProgress.memoizedState = oldContext)); + memoizeProps(workInProgress, newProps), + memoizeState(workInProgress, renderExpirationTime)); instance.props = newProps; - instance.state = oldContext; + instance.state = renderExpirationTime; instance.context = newUnmaskedContext; - return renderExpirationTime; + return oldProps; }, updateClassInstance: function( current, @@ -2275,16 +2194,16 @@ function ReactFiberClassComponent( renderExpirationTime ) { var ctor = workInProgress.type, - instance = workInProgress.stateNode, - oldProps = workInProgress.memoizedProps, - newProps = workInProgress.pendingProps; - instance.props = oldProps; - var oldContext = instance.context, + instance = workInProgress.stateNode; + instance.props = workInProgress.memoizedProps; + instance.state = workInProgress.memoizedState; + var oldProps = workInProgress.memoizedProps, + newProps = workInProgress.pendingProps, + oldContext = instance.context, newUnmaskedContext = getUnmaskedContext(workInProgress); newUnmaskedContext = getMaskedContext(workInProgress, newUnmaskedContext); - var getDerivedStateFromProps = ctor.getDerivedStateFromProps; (ctor = - "function" === typeof getDerivedStateFromProps || + "function" === typeof ctor.getDerivedStateFromProps || "function" === typeof instance.getSnapshotBeforeUpdate) || ("function" !== typeof instance.UNSAFE_componentWillReceiveProps && "function" !== typeof instance.componentWillReceiveProps) || @@ -2296,28 +2215,42 @@ function ReactFiberClassComponent( newUnmaskedContext )); oldContext = workInProgress.memoizedState; - var newState = (instance.state = oldContext), - updateQueue = workInProgress.updateQueue; - null !== updateQueue && - (processUpdateQueue( + renderExpirationTime = + null !== workInProgress.updateQueue + ? processUpdateQueue( + current, + workInProgress, + workInProgress.updateQueue, + instance, + newProps, + renderExpirationTime + ) + : oldContext; + var derivedStateFromProps = void 0; + oldProps !== newProps && + (derivedStateFromProps = callGetDerivedStateFromProps( workInProgress, - updateQueue, - newProps, instance, + newProps, renderExpirationTime - ), - (newState = workInProgress.memoizedState)); - "function" === typeof getDerivedStateFromProps && - (applyDerivedStateFromProps( - workInProgress, - getDerivedStateFromProps, - newProps - ), - (newState = workInProgress.memoizedState)); + )); + if (null !== derivedStateFromProps && void 0 !== derivedStateFromProps) { + renderExpirationTime = + null === renderExpirationTime || void 0 === renderExpirationTime + ? derivedStateFromProps + : Object.assign({}, renderExpirationTime, derivedStateFromProps); + var _updateQueue3 = workInProgress.updateQueue; + null !== _updateQueue3 && + (_updateQueue3.baseState = Object.assign( + {}, + _updateQueue3.baseState, + derivedStateFromProps + )); + } if ( !( oldProps !== newProps || - oldContext !== newState || + oldContext !== renderExpirationTime || hasContextChanged() || (null !== workInProgress.updateQueue && workInProgress.updateQueue.hasForceUpdate) @@ -2331,15 +2264,15 @@ function ReactFiberClassComponent( "function" !== typeof instance.getSnapshotBeforeUpdate || (oldProps === current.memoizedProps && oldContext === current.memoizedState) || - (workInProgress.effectTag |= 256), + (workInProgress.effectTag |= 2048), !1 ); - (renderExpirationTime = checkShouldComponentUpdate( + (derivedStateFromProps = checkShouldComponentUpdate( workInProgress, oldProps, newProps, oldContext, - newState, + renderExpirationTime, newUnmaskedContext )) ? (ctor || @@ -2348,19 +2281,19 @@ function ReactFiberClassComponent( ("function" === typeof instance.componentWillUpdate && instance.componentWillUpdate( newProps, - newState, + renderExpirationTime, newUnmaskedContext ), "function" === typeof instance.UNSAFE_componentWillUpdate && instance.UNSAFE_componentWillUpdate( newProps, - newState, + renderExpirationTime, newUnmaskedContext )), "function" === typeof instance.componentDidUpdate && (workInProgress.effectTag |= 4), "function" === typeof instance.getSnapshotBeforeUpdate && - (workInProgress.effectTag |= 256)) + (workInProgress.effectTag |= 2048)) : ("function" !== typeof instance.componentDidUpdate || (oldProps === current.memoizedProps && oldContext === current.memoizedState) || @@ -2368,13 +2301,13 @@ function ReactFiberClassComponent( "function" !== typeof instance.getSnapshotBeforeUpdate || (oldProps === current.memoizedProps && oldContext === current.memoizedState) || - (workInProgress.effectTag |= 256), - (workInProgress.memoizedProps = newProps), - (workInProgress.memoizedState = newState)); + (workInProgress.effectTag |= 2048), + memoizeProps(workInProgress, newProps), + memoizeState(workInProgress, renderExpirationTime)); instance.props = newProps; - instance.state = newState; + instance.state = renderExpirationTime; instance.context = newUnmaskedContext; - return renderExpirationTime; + return derivedStateFromProps; } }; } @@ -2498,11 +2431,11 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime )), - (current.return = returnFiber), + (current["return"] = returnFiber), current ); current = useFiber(current, textContent, expirationTime); - current.return = returnFiber; + current["return"] = returnFiber; return current; } function updateElement(returnFiber, current, element, expirationTime) { @@ -2510,7 +2443,7 @@ function ChildReconciler(shouldTrackSideEffects) { return ( (expirationTime = useFiber(current, element.props, expirationTime)), (expirationTime.ref = coerceRef(returnFiber, current, element)), - (expirationTime.return = returnFiber), + (expirationTime["return"] = returnFiber), expirationTime ); expirationTime = createFiberFromElement( @@ -2519,7 +2452,7 @@ function ChildReconciler(shouldTrackSideEffects) { expirationTime ); expirationTime.ref = coerceRef(returnFiber, current, element); - expirationTime.return = returnFiber; + expirationTime["return"] = returnFiber; return expirationTime; } function updatePortal(returnFiber, current, portal, expirationTime) { @@ -2535,11 +2468,11 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime )), - (current.return = returnFiber), + (current["return"] = returnFiber), current ); current = useFiber(current, portal.children || [], expirationTime); - current.return = returnFiber; + current["return"] = returnFiber; return current; } function updateFragment(returnFiber, current, fragment, expirationTime, key) { @@ -2551,11 +2484,11 @@ function ChildReconciler(shouldTrackSideEffects) { expirationTime, key )), - (current.return = returnFiber), + (current["return"] = returnFiber), current ); current = useFiber(current, fragment, expirationTime); - current.return = returnFiber; + current["return"] = returnFiber; return current; } function createChild(returnFiber, newChild, expirationTime) { @@ -2566,7 +2499,7 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime )), - (newChild.return = returnFiber), + (newChild["return"] = returnFiber), newChild ); if ("object" === typeof newChild && null !== newChild) { @@ -2579,7 +2512,7 @@ function ChildReconciler(shouldTrackSideEffects) { expirationTime )), (expirationTime.ref = coerceRef(returnFiber, null, newChild)), - (expirationTime.return = returnFiber), + (expirationTime["return"] = returnFiber), expirationTime ); case REACT_PORTAL_TYPE: @@ -2589,7 +2522,7 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime )), - (newChild.return = returnFiber), + (newChild["return"] = returnFiber), newChild ); } @@ -2601,7 +2534,7 @@ function ChildReconciler(shouldTrackSideEffects) { expirationTime, null )), - (newChild.return = returnFiber), + (newChild["return"] = returnFiber), newChild ); throwOnInvalidObjectType(returnFiber, newChild); @@ -2788,21 +2721,17 @@ function ChildReconciler(shouldTrackSideEffects) { newChildren[newIdx], expirationTime )) - ) - shouldTrackSideEffects && - null !== nextOldFiber.alternate && - oldFiber.delete( + ) { + if (shouldTrackSideEffects && null !== nextOldFiber.alternate) + oldFiber["delete"]( null === nextOldFiber.key ? newIdx : nextOldFiber.key - ), - (currentFirstChild = placeChild( - nextOldFiber, - currentFirstChild, - newIdx - )), - null === previousNewFiber - ? (resultingFirstChild = nextOldFiber) - : (previousNewFiber.sibling = nextOldFiber), - (previousNewFiber = nextOldFiber); + ); + currentFirstChild = placeChild(nextOldFiber, currentFirstChild, newIdx); + null === previousNewFiber + ? (resultingFirstChild = nextOldFiber) + : (previousNewFiber.sibling = nextOldFiber); + previousNewFiber = nextOldFiber; + } shouldTrackSideEffects && oldFiber.forEach(function(child) { return deleteChild(returnFiber, child); @@ -2876,22 +2805,24 @@ function ChildReconciler(shouldTrackSideEffects) { !step.done; newIdx++, step = newChildrenIterable.next() ) - (step = updateFromMap( - oldFiber, - returnFiber, - newIdx, - step.value, - expirationTime - )), - null !== step && - (shouldTrackSideEffects && - null !== step.alternate && - oldFiber.delete(null === step.key ? newIdx : step.key), - (currentFirstChild = placeChild(step, currentFirstChild, newIdx)), - null === previousNewFiber - ? (iteratorFn = step) - : (previousNewFiber.sibling = step), - (previousNewFiber = step)); + if ( + ((step = updateFromMap( + oldFiber, + returnFiber, + newIdx, + step.value, + expirationTime + )), + null !== step) + ) { + if (shouldTrackSideEffects && null !== step.alternate) + oldFiber["delete"](null === step.key ? newIdx : step.key); + currentFirstChild = placeChild(step, currentFirstChild, newIdx); + null === previousNewFiber + ? (iteratorFn = step) + : (previousNewFiber.sibling = step); + previousNewFiber = step; + } shouldTrackSideEffects && oldFiber.forEach(function(child) { return deleteChild(returnFiber, child); @@ -2930,7 +2861,7 @@ function ChildReconciler(shouldTrackSideEffects) { isObject, newChild ); - currentFirstChild.return = returnFiber; + currentFirstChild["return"] = returnFiber; returnFiber = currentFirstChild; break a; } else { @@ -2947,7 +2878,7 @@ function ChildReconciler(shouldTrackSideEffects) { expirationTime, newChild.key )), - (currentFirstChild.return = returnFiber), + (currentFirstChild["return"] = returnFiber), (returnFiber = currentFirstChild)) : ((expirationTime = createFiberFromElement( newChild, @@ -2959,7 +2890,7 @@ function ChildReconciler(shouldTrackSideEffects) { currentFirstChild, newChild )), - (expirationTime.return = returnFiber), + (expirationTime["return"] = returnFiber), (returnFiber = expirationTime)); } return placeSingleChild(returnFiber); @@ -2983,7 +2914,7 @@ function ChildReconciler(shouldTrackSideEffects) { newChild.children || [], expirationTime ); - currentFirstChild.return = returnFiber; + currentFirstChild["return"] = returnFiber; returnFiber = currentFirstChild; break a; } else { @@ -2998,7 +2929,7 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime ); - currentFirstChild.return = returnFiber; + currentFirstChild["return"] = returnFiber; returnFiber = currentFirstChild; } return placeSingleChild(returnFiber); @@ -3013,7 +2944,7 @@ function ChildReconciler(shouldTrackSideEffects) { newChild, expirationTime )), - (currentFirstChild.return = returnFiber), + (currentFirstChild["return"] = returnFiber), (returnFiber = currentFirstChild)) : (deleteRemainingChildren(returnFiber, currentFirstChild), (currentFirstChild = createFiberFromText( @@ -3021,7 +2952,7 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime )), - (currentFirstChild.return = returnFiber), + (currentFirstChild["return"] = returnFiber), (returnFiber = currentFirstChild)), placeSingleChild(returnFiber) ); @@ -3107,10 +3038,10 @@ function ReactFiberBeginWork( workInProgress, shouldUpdate, hasContext, + didCaptureError, renderExpirationTime ) { markRef(current, workInProgress); - var didCaptureError = 0 !== (workInProgress.effectTag & 64); if (!shouldUpdate && !didCaptureError) return ( hasContext && invalidateContextProvider(workInProgress, !1), @@ -3158,8 +3089,11 @@ function ReactFiberBeginWork( renderExpirationTime ) { var fiber = workInProgress.child; - null !== fiber && (fiber.return = workInProgress); - for (; null !== fiber; ) { + for ( + null !== fiber && (fiber["return"] = workInProgress); + null !== fiber; + + ) { switch (fiber.tag) { case 12: var nextFiber = fiber.stateNode | 0; @@ -3182,7 +3116,7 @@ function ReactFiberBeginWork( ) alternate.expirationTime = renderExpirationTime; else break; - nextFiber = nextFiber.return; + nextFiber = nextFiber["return"]; } nextFiber = null; } else nextFiber = fiber.child; @@ -3193,7 +3127,7 @@ function ReactFiberBeginWork( default: nextFiber = fiber.child; } - if (null !== nextFiber) nextFiber.return = fiber; + if (null !== nextFiber) nextFiber["return"] = fiber; else for (nextFiber = fiber; null !== nextFiber; ) { if (nextFiber === workInProgress) { @@ -3202,11 +3136,10 @@ function ReactFiberBeginWork( } fiber = nextFiber.sibling; if (null !== fiber) { - fiber.return = nextFiber.return; nextFiber = fiber; break; } - nextFiber = nextFiber.return; + nextFiber = nextFiber["return"]; } fiber = nextFiber; } @@ -3218,10 +3151,8 @@ function ReactFiberBeginWork( ) { var context = workInProgress.type._context, newProps = workInProgress.pendingProps, - oldProps = workInProgress.memoizedProps, - canBailOnProps = !0; - if (hasLegacyContextChanged()) canBailOnProps = !1; - else if (oldProps === newProps) + oldProps = workInProgress.memoizedProps; + if (!hasLegacyContextChanged() && oldProps === newProps) return ( (workInProgress.stateNode = 0), pushProvider(workInProgress), @@ -3231,7 +3162,7 @@ function ReactFiberBeginWork( workInProgress.memoizedProps = newProps; if (null === oldProps) newValue = 1073741823; else if (oldProps.value === newProps.value) { - if (oldProps.children === newProps.children && canBailOnProps) + if (oldProps.children === newProps.children) return ( (workInProgress.stateNode = 0), pushProvider(workInProgress), @@ -3245,7 +3176,7 @@ function ReactFiberBeginWork( (0 !== oldValue || 1 / oldValue === 1 / newValue)) || (oldValue !== oldValue && newValue !== newValue) ) { - if (oldProps.children === newProps.children && canBailOnProps) + if (oldProps.children === newProps.children) return ( (workInProgress.stateNode = 0), pushProvider(workInProgress), @@ -3260,7 +3191,7 @@ function ReactFiberBeginWork( (newValue |= 0), 0 === newValue) ) { - if (oldProps.children === newProps.children && canBailOnProps) + if (oldProps.children === newProps.children) return ( (workInProgress.stateNode = 0), pushProvider(workInProgress), @@ -3292,14 +3223,14 @@ function ReactFiberBeginWork( current.expirationTime ); workInProgress.child = newChild; - for (newChild.return = workInProgress; null !== current.sibling; ) + for (newChild["return"] = workInProgress; null !== current.sibling; ) (current = current.sibling), (newChild = newChild.sibling = createWorkInProgress( current, current.pendingProps, current.expirationTime )), - (newChild.return = workInProgress); + (newChild["return"] = workInProgress); newChild.sibling = null; } return workInProgress.child; @@ -3331,6 +3262,7 @@ function ReactFiberBeginWork( } ); var adoptClassInstance = config.adoptClassInstance, + callGetDerivedStateFromProps = config.callGetDerivedStateFromProps, constructClassInstance = config.constructClassInstance, mountClassInstance = config.mountClassInstance, resumeMountClassInstance = config.resumeMountClassInstance, @@ -3379,13 +3311,20 @@ function ReactFiberBeginWork( (workInProgress.tag = 2), (workInProgress.memoizedState = null !== fn.state && void 0 !== fn.state ? fn.state : null), - (unmaskedContext = unmaskedContext.getDerivedStateFromProps), - "function" === typeof unmaskedContext && - applyDerivedStateFromProps( + "function" === typeof unmaskedContext.getDerivedStateFromProps && + ((props = callGetDerivedStateFromProps( workInProgress, - unmaskedContext, - props - ), + fn, + props, + workInProgress.memoizedState + )), + null !== props && + void 0 !== props && + (workInProgress.memoizedState = Object.assign( + {}, + workInProgress.memoizedState, + props + ))), (props = pushLegacyContextProvider(workInProgress)), adoptClassInstance(workInProgress, fn), mountClassInstance(workInProgress, renderExpirationTime), @@ -3394,6 +3333,7 @@ function ReactFiberBeginWork( workInProgress, !0, props, + !1, renderExpirationTime ))) : ((workInProgress.tag = 1), @@ -3421,100 +3361,103 @@ function ReactFiberBeginWork( current ); case 2: - return ( - (props = pushLegacyContextProvider(workInProgress)), - null === current - ? null === workInProgress.stateNode - ? (constructClassInstance( - workInProgress, - workInProgress.pendingProps, - renderExpirationTime - ), - mountClassInstance(workInProgress, renderExpirationTime), - (fn = !0)) - : (fn = resumeMountClassInstance( - workInProgress, - renderExpirationTime - )) - : (fn = updateClassInstance( - current, + props = pushLegacyContextProvider(workInProgress); + null === current + ? null === workInProgress.stateNode + ? (constructClassInstance( + workInProgress, + workInProgress.pendingProps + ), + mountClassInstance(workInProgress, renderExpirationTime), + (fn = !0)) + : (fn = resumeMountClassInstance( workInProgress, renderExpirationTime - )), - finishClassComponent( + )) + : (fn = updateClassInstance( + current, + workInProgress, + renderExpirationTime + )); + unmaskedContext = !1; + var updateQueue = workInProgress.updateQueue; + null !== updateQueue && + null !== updateQueue.capturedValues && + (unmaskedContext = fn = !0); + return finishClassComponent( + current, + workInProgress, + fn, + props, + unmaskedContext, + renderExpirationTime + ); + case 3: + a: if ( + (pushHostRootContext(workInProgress), + (fn = workInProgress.updateQueue), + null !== fn) + ) { + unmaskedContext = workInProgress.memoizedState; + props = processUpdateQueue( current, workInProgress, fn, - props, + null, + null, renderExpirationTime - ) - ); - case 3: - return ( - pushHostRootContext(workInProgress), - (props = workInProgress.updateQueue), - null !== props - ? ((fn = workInProgress.memoizedState), - (fn = null !== fn ? fn.element : null), - processUpdateQueue( + ); + workInProgress.memoizedState = props; + fn = workInProgress.updateQueue; + if (null !== fn && null !== fn.capturedValues) fn = null; + else if (unmaskedContext === props) { + resetHydrationState(); + current = bailoutOnAlreadyFinishedWork(current, workInProgress); + break a; + } else fn = props.element; + unmaskedContext = workInProgress.stateNode; + (null === current || null === current.child) && + unmaskedContext.hydrate && + enterHydrationState(workInProgress) + ? ((workInProgress.effectTag |= 2), + (workInProgress.child = mountChildFibers( workInProgress, - props, - workInProgress.pendingProps, null, + fn, renderExpirationTime - ), - (props = workInProgress.memoizedState.element), - props === fn - ? (resetHydrationState(), - (current = bailoutOnAlreadyFinishedWork( - current, - workInProgress - ))) - : ((fn = workInProgress.stateNode), - (null === current || null === current.child) && - fn.hydrate && - enterHydrationState(workInProgress) - ? ((workInProgress.effectTag |= 2), - (workInProgress.child = mountChildFibers( - workInProgress, - null, - props, - renderExpirationTime - ))) - : (resetHydrationState(), - reconcileChildren(current, workInProgress, props)), - (current = workInProgress.child))) + ))) : (resetHydrationState(), - (current = bailoutOnAlreadyFinishedWork( - current, - workInProgress - ))), - current - ); + reconcileChildren(current, workInProgress, fn)); + workInProgress.memoizedState = props; + current = workInProgress.child; + } else + resetHydrationState(), + (current = bailoutOnAlreadyFinishedWork(current, workInProgress)); + return current; case 5: a: { pushHostContext(workInProgress); null === current && tryToClaimNextHydratableInstance(workInProgress); props = workInProgress.type; - var memoizedProps = workInProgress.memoizedProps; + updateQueue = workInProgress.memoizedProps; fn = workInProgress.pendingProps; unmaskedContext = null !== current ? current.memoizedProps : null; - if (!hasLegacyContextChanged() && memoizedProps === fn) { + if (!hasLegacyContextChanged() && updateQueue === fn) { if ( - (memoizedProps = + (updateQueue = workInProgress.mode & 1 && shouldDeprioritizeSubtree(props, fn)) ) workInProgress.expirationTime = 1073741823; - if (!memoizedProps || 1073741823 !== renderExpirationTime) { + if (!updateQueue || 1073741823 !== renderExpirationTime) { current = bailoutOnAlreadyFinishedWork(current, workInProgress); break a; } } - memoizedProps = fn.children; + updateQueue = fn.children; shouldSetTextContent(props, fn) - ? (memoizedProps = null) + ? (updateQueue = null) : unmaskedContext && shouldSetTextContent(props, unmaskedContext) && (workInProgress.effectTag |= 16); @@ -3525,7 +3468,7 @@ function ReactFiberBeginWork( ? ((workInProgress.expirationTime = 1073741823), (workInProgress.memoizedProps = fn), (current = null)) - : (reconcileChildren(current, workInProgress, memoizedProps), + : (reconcileChildren(current, workInProgress, updateQueue), (workInProgress.memoizedProps = fn), (current = workInProgress.child)); } @@ -3591,21 +3534,14 @@ function ReactFiberBeginWork( ); case 14: return ( - (props = workInProgress.type.render), - (renderExpirationTime = workInProgress.pendingProps), - (fn = workInProgress.ref), - hasLegacyContextChanged() || - workInProgress.memoizedProps !== renderExpirationTime || - fn !== (null !== current ? current.ref : null) - ? ((props = props(renderExpirationTime, fn)), - reconcileChildren(current, workInProgress, props), - (workInProgress.memoizedProps = renderExpirationTime), - (current = workInProgress.child)) - : (current = bailoutOnAlreadyFinishedWork( - current, - workInProgress - )), - current + (renderExpirationTime = workInProgress.type.render), + (renderExpirationTime = renderExpirationTime( + workInProgress.pendingProps, + workInProgress.ref + )), + reconcileChildren(current, workInProgress, renderExpirationTime), + (workInProgress.memoizedProps = renderExpirationTime), + workInProgress.child ); case 10: return ( @@ -3654,13 +3590,13 @@ function ReactFiberBeginWork( a: { fn = workInProgress.type; unmaskedContext = workInProgress.pendingProps; - memoizedProps = workInProgress.memoizedProps; + updateQueue = workInProgress.memoizedProps; props = fn._currentValue; var changedBits = fn._changedBits; if ( hasLegacyContextChanged() || 0 !== changedBits || - memoizedProps !== unmaskedContext + updateQueue !== unmaskedContext ) { workInProgress.memoizedProps = unmaskedContext; var observedBits = unmaskedContext.unstable_observedBits; @@ -3674,13 +3610,12 @@ function ReactFiberBeginWork( changedBits, renderExpirationTime ); - else if (memoizedProps === unmaskedContext) { + else if (updateQueue === unmaskedContext) { current = bailoutOnAlreadyFinishedWork(current, workInProgress); break a; } renderExpirationTime = unmaskedContext.children; renderExpirationTime = renderExpirationTime(props); - workInProgress.effectTag |= 1; reconcileChildren(current, workInProgress, renderExpirationTime); current = workInProgress.child; } else @@ -3746,7 +3681,18 @@ function ReactFiberCompleteWork( case 1: return null; case 2: - return popLegacyContextProvider(workInProgress), null; + return ( + popLegacyContextProvider(workInProgress), + (current = workInProgress.stateNode), + (newProps = workInProgress.updateQueue), + null !== newProps && + null !== newProps.capturedValues && + ((workInProgress.effectTag &= -65), + "function" === typeof current.componentDidCatch + ? (workInProgress.effectTag |= 256) + : (newProps.capturedValues = null)), + null + ); case 3: popHostContainer(workInProgress); popTopLevelLegacyContextObject(workInProgress); @@ -3757,6 +3703,10 @@ function ReactFiberCompleteWork( if (null === current || null === current.child) popHydrationState(workInProgress), (workInProgress.effectTag &= -3); updateHostContainer(workInProgress); + current = workInProgress.updateQueue; + null !== current && + null !== current.capturedValues && + (workInProgress.effectTag |= 256); return null; case 5: popHostContext(workInProgress); @@ -3764,10 +3714,10 @@ function ReactFiberCompleteWork( var type = workInProgress.type; if (null !== current && null != workInProgress.stateNode) { var oldProps = current.memoizedProps, - instance = workInProgress.stateNode, + _instance = workInProgress.stateNode, currentHostContext = getHostContext(); - instance = prepareUpdate( - instance, + _instance = prepareUpdate( + _instance, type, oldProps, newProps, @@ -3777,7 +3727,7 @@ function ReactFiberCompleteWork( updateHostComponent( current, workInProgress, - instance, + _instance, type, oldProps, newProps, @@ -3824,20 +3774,21 @@ function ReactFiberCompleteWork( 4 !== currentHostContext.tag && null !== currentHostContext.child ) { - currentHostContext.child.return = currentHostContext; + currentHostContext.child["return"] = currentHostContext; currentHostContext = currentHostContext.child; continue; } if (currentHostContext === workInProgress) break; for (; null === currentHostContext.sibling; ) { if ( - null === currentHostContext.return || - currentHostContext.return === workInProgress + null === currentHostContext["return"] || + currentHostContext["return"] === workInProgress ) break a; - currentHostContext = currentHostContext.return; + currentHostContext = currentHostContext["return"]; } - currentHostContext.sibling.return = currentHostContext.return; + currentHostContext.sibling["return"] = + currentHostContext["return"]; currentHostContext = currentHostContext.sibling; } finalizeInitialChildren( @@ -3890,34 +3841,30 @@ function ReactFiberCompleteWork( ); workInProgress.tag = 8; type = []; - a: { - if ((oldProps = workInProgress.stateNode)) - oldProps.return = workInProgress; - for (; null !== oldProps; ) { - if ( - 5 === oldProps.tag || - 6 === oldProps.tag || - 4 === oldProps.tag - ) - invariant(!1, "A call cannot have host component children."); - else if (9 === oldProps.tag) - type.push(oldProps.pendingProps.value); - else if (null !== oldProps.child) { - oldProps.child.return = oldProps; - oldProps = oldProps.child; - continue; - } - for (; null === oldProps.sibling; ) { - if ( - null === oldProps.return || - oldProps.return === workInProgress - ) - break a; - oldProps = oldProps.return; - } - oldProps.sibling.return = oldProps.return; - oldProps = oldProps.sibling; + a: for ( + (oldProps = workInProgress.stateNode) && + (oldProps["return"] = workInProgress); + null !== oldProps; + + ) { + if (5 === oldProps.tag || 6 === oldProps.tag || 4 === oldProps.tag) + invariant(!1, "A call cannot have host component children."); + else if (9 === oldProps.tag) type.push(oldProps.pendingProps.value); + else if (null !== oldProps.child) { + oldProps.child["return"] = oldProps; + oldProps = oldProps.child; + continue; } + for (; null === oldProps.sibling; ) { + if ( + null === oldProps["return"] || + oldProps["return"] === workInProgress + ) + break a; + oldProps = oldProps["return"]; + } + oldProps.sibling["return"] = oldProps["return"]; + oldProps = oldProps.sibling; } oldProps = newProps.handler; newProps = oldProps(newProps.props, type); @@ -3962,536 +3909,53 @@ function ReactFiberCompleteWork( } }; } -function createCapturedValue(value, source) { - return { - value: value, - source: source, - stack: getStackAddendumByWorkInProgressFiber(source) - }; -} -function logError(boundary, errorInfo) { - var source = errorInfo.source, - stack = errorInfo.stack; - null === stack && (stack = getStackAddendumByWorkInProgressFiber(source)); - null !== source && getComponentName(source); - source = null !== stack ? stack : ""; - errorInfo = errorInfo.value; - null !== boundary && 2 === boundary.tag && getComponentName(boundary); - try { - if (errorInfo instanceof Error) { - var message = errorInfo.message, - name = errorInfo.name; - var errorToHandle = errorInfo; - try { - errorToHandle.message = - (message ? name + ": " + message : name) + - "\n\nThis error is located at:" + - source; - } catch (e) {} - } else - errorToHandle = - "string" === typeof errorInfo - ? Error(errorInfo + "\n\nThis error is located at:" + source) - : Error("Unspecified error at:" + source); - ExceptionsManager.handleException(errorToHandle, !1); - } catch (e) { - (e && e.suppressReactErrorLogging) || console.error(e); - } -} -function ReactFiberCommitWork(config, captureError) { - function safelyDetachRef(current) { - var ref = current.ref; - if (null !== ref) - if ("function" === typeof ref) - try { - ref(null); - } catch (refError) { - captureError(current, refError); - } - else ref.current = null; - } - function commitUnmount(current) { - "function" === typeof onCommitUnmount && onCommitUnmount(current); - switch (current.tag) { - case 2: - safelyDetachRef(current); - var _instance6 = current.stateNode; - if ("function" === typeof _instance6.componentWillUnmount) - try { - (_instance6.props = current.memoizedProps), - (_instance6.state = current.memoizedState), - _instance6.componentWillUnmount(); - } catch (unmountError) { - captureError(current, unmountError); - } - break; - case 5: - safelyDetachRef(current); - break; - case 7: - commitNestedUnmounts(current.stateNode); - break; - case 4: - mutation && unmountHostComponents(current); - } - } - function commitNestedUnmounts(root) { - for (var node = root; ; ) - if ( - (commitUnmount(node), - null === node.child || (mutation && 4 === node.tag)) - ) { - if (node === root) break; - for (; null === node.sibling; ) { - if (null === node.return || node.return === root) return; - node = node.return; - } - node.sibling.return = node.return; - node = node.sibling; - } else (node.child.return = node), (node = node.child); - } - function isHostParent(fiber) { - return 5 === fiber.tag || 3 === fiber.tag || 4 === fiber.tag; - } - function unmountHostComponents(current) { - for ( - var node = current, - currentParentIsValid = !1, - currentParent = void 0, - currentParentIsContainer = void 0; - ; - - ) { - if (!currentParentIsValid) { - currentParentIsValid = node.return; - a: for (;;) { - invariant( - null !== currentParentIsValid, - "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." - ); - switch (currentParentIsValid.tag) { - case 5: - currentParent = currentParentIsValid.stateNode; - currentParentIsContainer = !1; - break a; - case 3: - currentParent = currentParentIsValid.stateNode.containerInfo; - currentParentIsContainer = !0; - break a; - case 4: - currentParent = currentParentIsValid.stateNode.containerInfo; - currentParentIsContainer = !0; - break a; - } - currentParentIsValid = currentParentIsValid.return; - } - currentParentIsValid = !0; - } - if (5 === node.tag || 6 === node.tag) - commitNestedUnmounts(node), - currentParentIsContainer - ? removeChildFromContainer(currentParent, node.stateNode) - : removeChild(currentParent, node.stateNode); - else if ( - (4 === node.tag - ? (currentParent = node.stateNode.containerInfo) - : commitUnmount(node), - null !== node.child) - ) { - node.child.return = node; - node = node.child; - continue; - } - if (node === current) break; - for (; null === node.sibling; ) { - if (null === node.return || node.return === current) return; - node = node.return; - 4 === node.tag && (currentParentIsValid = !1); - } - node.sibling.return = node.return; - node = node.sibling; - } - } - var getPublicInstance = config.getPublicInstance, - mutation = config.mutation; - config = config.persistence; - mutation || - (config - ? invariant(!1, "Persistent reconciler is disabled.") - : invariant(!1, "Noop reconciler is disabled.")); - var commitMount = mutation.commitMount, - commitUpdate = mutation.commitUpdate, - resetTextContent = mutation.resetTextContent, - commitTextUpdate = mutation.commitTextUpdate, - appendChild = mutation.appendChild, - appendChildToContainer = mutation.appendChildToContainer, - insertBefore = mutation.insertBefore, - insertInContainerBefore = mutation.insertInContainerBefore, - removeChild = mutation.removeChild, - removeChildFromContainer = mutation.removeChildFromContainer; - return { - commitBeforeMutationLifeCycles: function(current, finishedWork) { - switch (finishedWork.tag) { - case 2: - if (finishedWork.effectTag & 256 && null !== current) { - var prevProps = current.memoizedProps, - prevState = current.memoizedState; - current = finishedWork.stateNode; - current.props = finishedWork.memoizedProps; - current.state = finishedWork.memoizedState; - finishedWork = current.getSnapshotBeforeUpdate( - prevProps, - prevState - ); - current.__reactInternalSnapshotBeforeUpdate = finishedWork; - } - break; - case 3: - case 5: - case 6: - case 4: - break; - default: - invariant( - !1, - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); - } - }, - commitResetTextContent: function(current) { - resetTextContent(current.stateNode); - }, - commitPlacement: function(finishedWork) { - a: { - for (var parent = finishedWork.return; null !== parent; ) { - if (isHostParent(parent)) { - var parentFiber = parent; - break a; - } - parent = parent.return; - } - invariant( - !1, - "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." - ); - parentFiber = void 0; - } - var isContainer = (parent = void 0); - switch (parentFiber.tag) { - case 5: - parent = parentFiber.stateNode; - isContainer = !1; - break; - case 3: - parent = parentFiber.stateNode.containerInfo; - isContainer = !0; - break; - case 4: - parent = parentFiber.stateNode.containerInfo; - isContainer = !0; - break; - default: - invariant( - !1, - "Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue." - ); - } - parentFiber.effectTag & 16 && - (resetTextContent(parent), (parentFiber.effectTag &= -17)); - a: b: for (parentFiber = finishedWork; ; ) { - for (; null === parentFiber.sibling; ) { - if (null === parentFiber.return || isHostParent(parentFiber.return)) { - parentFiber = null; - break a; - } - parentFiber = parentFiber.return; - } - parentFiber.sibling.return = parentFiber.return; - for ( - parentFiber = parentFiber.sibling; - 5 !== parentFiber.tag && 6 !== parentFiber.tag; - - ) { - if (parentFiber.effectTag & 2) continue b; - if (null === parentFiber.child || 4 === parentFiber.tag) continue b; - else - (parentFiber.child.return = parentFiber), - (parentFiber = parentFiber.child); - } - if (!(parentFiber.effectTag & 2)) { - parentFiber = parentFiber.stateNode; - break a; - } - } - for (var node = finishedWork; ; ) { - if (5 === node.tag || 6 === node.tag) - parentFiber - ? isContainer - ? insertInContainerBefore(parent, node.stateNode, parentFiber) - : insertBefore(parent, node.stateNode, parentFiber) - : isContainer - ? appendChildToContainer(parent, node.stateNode) - : appendChild(parent, node.stateNode); - else if (4 !== node.tag && null !== node.child) { - node.child.return = node; - node = node.child; - continue; - } - if (node === finishedWork) break; - for (; null === node.sibling; ) { - if (null === node.return || node.return === finishedWork) return; - node = node.return; - } - node.sibling.return = node.return; - node = node.sibling; - } - }, - commitDeletion: function(current) { - unmountHostComponents(current); - current.return = null; - current.child = null; - current.alternate && - ((current.alternate.child = null), (current.alternate.return = null)); - }, - commitWork: function(current, finishedWork) { - switch (finishedWork.tag) { - case 2: - break; - case 5: - var _instance7 = finishedWork.stateNode; - if (null != _instance7) { - var newProps = finishedWork.memoizedProps; - current = null !== current ? current.memoizedProps : newProps; - var type = finishedWork.type, - updatePayload = finishedWork.updateQueue; - finishedWork.updateQueue = null; - null !== updatePayload && - commitUpdate( - _instance7, - updatePayload, - type, - current, - newProps, - finishedWork - ); - } - break; - case 6: - invariant( - null !== finishedWork.stateNode, - "This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue." - ); - _instance7 = finishedWork.memoizedProps; - commitTextUpdate( - finishedWork.stateNode, - null !== current ? current.memoizedProps : _instance7, - _instance7 - ); - break; - case 3: - break; - default: - invariant( - !1, - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); - } - }, - commitLifeCycles: function( - finishedRoot, - current, - finishedWork, - currentTime, - committedExpirationTime - ) { - switch (finishedWork.tag) { - case 2: - finishedRoot = finishedWork.stateNode; - finishedWork.effectTag & 4 && - (null === current - ? ((finishedRoot.props = finishedWork.memoizedProps), - (finishedRoot.state = finishedWork.memoizedState), - finishedRoot.componentDidMount()) - : ((currentTime = current.memoizedProps), - (current = current.memoizedState), - (finishedRoot.props = finishedWork.memoizedProps), - (finishedRoot.state = finishedWork.memoizedState), - finishedRoot.componentDidUpdate( - currentTime, - current, - finishedRoot.__reactInternalSnapshotBeforeUpdate - ))); - current = finishedWork.updateQueue; - null !== current && - ((finishedRoot.props = finishedWork.memoizedProps), - (finishedRoot.state = finishedWork.memoizedState), - commitUpdateQueue( - finishedWork, - current, - finishedRoot, - committedExpirationTime - )); - break; - case 3: - current = finishedWork.updateQueue; - if (null !== current) { - finishedRoot = null; - if (null !== finishedWork.child) - switch (finishedWork.child.tag) { - case 5: - finishedRoot = getPublicInstance( - finishedWork.child.stateNode - ); - break; - case 2: - finishedRoot = finishedWork.child.stateNode; - } - commitUpdateQueue( - finishedWork, - current, - finishedRoot, - committedExpirationTime - ); - } - break; - case 5: - committedExpirationTime = finishedWork.stateNode; - null === current && - finishedWork.effectTag & 4 && - commitMount( - committedExpirationTime, - finishedWork.type, - finishedWork.memoizedProps, - finishedWork - ); - break; - case 6: - break; - case 4: - break; - default: - invariant( - !1, - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); - } - }, - commitAttachRef: function(finishedWork) { - var ref = finishedWork.ref; - if (null !== ref) { - var _instance5 = finishedWork.stateNode; - switch (finishedWork.tag) { - case 5: - finishedWork = getPublicInstance(_instance5); - break; - default: - finishedWork = _instance5; - } - "function" === typeof ref - ? ref(finishedWork) - : (ref.current = finishedWork); - } - }, - commitDetachRef: function(current) { - current = current.ref; - null !== current && - ("function" === typeof current - ? current(null) - : (current.current = null)); - } - }; -} function ReactFiberUnwindWork( hostContext, legacyContext, newContext, scheduleWork, - markLegacyErrorBoundaryAsFailed, - isAlreadyFailedLegacyErrorBoundary, - onUncaughtError + isAlreadyFailedLegacyErrorBoundary ) { - function createRootErrorUpdate(fiber, errorInfo, expirationTime) { - expirationTime = createUpdate(expirationTime); - expirationTime.tag = 3; - expirationTime.payload = { element: null }; - var error = errorInfo.value; - expirationTime.callback = function() { - onUncaughtError(error); - logError(fiber, errorInfo); - }; - return expirationTime; - } - function createClassErrorUpdate(fiber, errorInfo, expirationTime) { - expirationTime = createUpdate(expirationTime); - expirationTime.tag = 3; - var inst = fiber.stateNode; - null !== inst && - "function" === typeof inst.componentDidCatch && - (expirationTime.callback = function() { - markLegacyErrorBoundaryAsFailed(this); - var error = errorInfo.value, - stack = errorInfo.stack; - logError(fiber, errorInfo); - this.componentDidCatch(error, { - componentStack: null !== stack ? stack : "" - }); - }); - return expirationTime; - } var popHostContainer = hostContext.popHostContainer, popHostContext = hostContext.popHostContext, popLegacyContextProvider = legacyContext.popContextProvider, popTopLevelLegacyContextObject = legacyContext.popTopLevelContextObject, popProvider = newContext.popProvider; return { - throwException: function( - returnFiber, - sourceFiber, - rawValue, - renderExpirationTime - ) { + throwException: function(returnFiber, sourceFiber, rawValue) { sourceFiber.effectTag |= 512; sourceFiber.firstEffect = sourceFiber.lastEffect = null; - sourceFiber = createCapturedValue(rawValue, sourceFiber); + sourceFiber = { + value: rawValue, + source: sourceFiber, + stack: getStackAddendumByWorkInProgressFiber(sourceFiber) + }; do { switch (returnFiber.tag) { case 3: + ensureUpdateQueues(returnFiber); + returnFiber.updateQueue.capturedValues = [sourceFiber]; returnFiber.effectTag |= 1024; - sourceFiber = createRootErrorUpdate( - returnFiber, - sourceFiber, - renderExpirationTime - ); - enqueueCapturedUpdate( - returnFiber, - sourceFiber, - renderExpirationTime - ); return; case 2: - rawValue = sourceFiber; - var _instance = returnFiber.stateNode; if ( + ((rawValue = returnFiber.stateNode), 0 === (returnFiber.effectTag & 64) && - null !== _instance && - "function" === typeof _instance.componentDidCatch && - !isAlreadyFailedLegacyErrorBoundary(_instance) + null !== rawValue && + "function" === typeof rawValue.componentDidCatch && + !isAlreadyFailedLegacyErrorBoundary(rawValue)) ) { + ensureUpdateQueues(returnFiber); + rawValue = returnFiber.updateQueue; + var capturedValues = rawValue.capturedValues; + null === capturedValues + ? (rawValue.capturedValues = [sourceFiber]) + : capturedValues.push(sourceFiber); returnFiber.effectTag |= 1024; - sourceFiber = createClassErrorUpdate( - returnFiber, - rawValue, - renderExpirationTime - ); - enqueueCapturedUpdate( - returnFiber, - sourceFiber, - renderExpirationTime - ); return; } } - returnFiber = returnFiber.return; + returnFiber = returnFiber["return"]; } while (null !== returnFiber); }, unwindWork: function(workInProgress) { @@ -4541,9 +4005,479 @@ function ReactFiberUnwindWork( case 13: popProvider(interruptedWork); } + } + }; +} +function logError(boundary, errorInfo) { + var source = errorInfo.source, + stack = errorInfo.stack; + null === stack && (stack = getStackAddendumByWorkInProgressFiber(source)); + null !== source && getComponentName(source); + source = null !== stack ? stack : ""; + errorInfo = errorInfo.value; + null !== boundary && 2 === boundary.tag && getComponentName(boundary); + try { + if (errorInfo instanceof Error) { + var message = errorInfo.message, + name = errorInfo.name; + var errorToHandle = errorInfo; + try { + errorToHandle.message = + (message ? name + ": " + message : name) + + "\n\nThis error is located at:" + + source; + } catch (e) {} + } else + errorToHandle = + "string" === typeof errorInfo + ? Error(errorInfo + "\n\nThis error is located at:" + source) + : Error("Unspecified error at:" + source); + ExceptionsManager.handleException(errorToHandle, !1); + } catch (e) { + (e && e.suppressReactErrorLogging) || console.error(e); + } +} +function ReactFiberCommitWork( + config, + captureError, + scheduleWork, + computeExpirationForFiber, + markLegacyErrorBoundaryAsFailed +) { + function safelyDetachRef(current) { + var ref = current.ref; + if (null !== ref) + if ("function" === typeof ref) + try { + ref(null); + } catch (refError) { + captureError(current, refError); + } + else ref.current = null; + } + function commitUnmount(current) { + "function" === typeof onCommitUnmount && onCommitUnmount(current); + switch (current.tag) { + case 2: + safelyDetachRef(current); + var _instance7 = current.stateNode; + if ("function" === typeof _instance7.componentWillUnmount) + try { + (_instance7.props = current.memoizedProps), + (_instance7.state = current.memoizedState), + _instance7.componentWillUnmount(); + } catch (unmountError) { + captureError(current, unmountError); + } + break; + case 5: + safelyDetachRef(current); + break; + case 7: + commitNestedUnmounts(current.stateNode); + break; + case 4: + mutation && unmountHostComponents(current); + } + } + function commitNestedUnmounts(root) { + for (var node = root; ; ) + if ( + (commitUnmount(node), + null === node.child || (mutation && 4 === node.tag)) + ) { + if (node === root) break; + for (; null === node.sibling; ) { + if (null === node["return"] || node["return"] === root) return; + node = node["return"]; + } + node.sibling["return"] = node["return"]; + node = node.sibling; + } else (node.child["return"] = node), (node = node.child); + } + function isHostParent(fiber) { + return 5 === fiber.tag || 3 === fiber.tag || 4 === fiber.tag; + } + function unmountHostComponents(current) { + for ( + var node = current, + currentParentIsValid = !1, + currentParent = void 0, + currentParentIsContainer = void 0; + ; + + ) { + if (!currentParentIsValid) { + currentParentIsValid = node["return"]; + a: for (;;) { + invariant( + null !== currentParentIsValid, + "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." + ); + switch (currentParentIsValid.tag) { + case 5: + currentParent = currentParentIsValid.stateNode; + currentParentIsContainer = !1; + break a; + case 3: + currentParent = currentParentIsValid.stateNode.containerInfo; + currentParentIsContainer = !0; + break a; + case 4: + currentParent = currentParentIsValid.stateNode.containerInfo; + currentParentIsContainer = !0; + break a; + } + currentParentIsValid = currentParentIsValid["return"]; + } + currentParentIsValid = !0; + } + if (5 === node.tag || 6 === node.tag) + commitNestedUnmounts(node), + currentParentIsContainer + ? removeChildFromContainer(currentParent, node.stateNode) + : removeChild(currentParent, node.stateNode); + else if ( + (4 === node.tag + ? (currentParent = node.stateNode.containerInfo) + : commitUnmount(node), + null !== node.child) + ) { + node.child["return"] = node; + node = node.child; + continue; + } + if (node === current) break; + for (; null === node.sibling; ) { + if (null === node["return"] || node["return"] === current) return; + node = node["return"]; + 4 === node.tag && (currentParentIsValid = !1); + } + node.sibling["return"] = node["return"]; + node = node.sibling; + } + } + var getPublicInstance = config.getPublicInstance, + mutation = config.mutation; + config = config.persistence; + mutation || + (config + ? invariant(!1, "Persistent reconciler is disabled.") + : invariant(!1, "Noop reconciler is disabled.")); + var commitMount = mutation.commitMount, + commitUpdate = mutation.commitUpdate, + resetTextContent = mutation.resetTextContent, + commitTextUpdate = mutation.commitTextUpdate, + appendChild = mutation.appendChild, + appendChildToContainer = mutation.appendChildToContainer, + insertBefore = mutation.insertBefore, + insertInContainerBefore = mutation.insertInContainerBefore, + removeChild = mutation.removeChild, + removeChildFromContainer = mutation.removeChildFromContainer; + return { + commitBeforeMutationLifeCycles: function(current, finishedWork) { + switch (finishedWork.tag) { + case 2: + if (finishedWork.effectTag & 2048 && null !== current) { + var prevProps = current.memoizedProps, + prevState = current.memoizedState; + current = finishedWork.stateNode; + current.props = finishedWork.memoizedProps; + current.state = finishedWork.memoizedState; + finishedWork = current.getSnapshotBeforeUpdate( + prevProps, + prevState + ); + current.__reactInternalSnapshotBeforeUpdate = finishedWork; + } + break; + case 3: + case 5: + case 6: + case 4: + break; + default: + invariant( + !1, + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); + } }, - createRootErrorUpdate: createRootErrorUpdate, - createClassErrorUpdate: createClassErrorUpdate + commitResetTextContent: function(current) { + resetTextContent(current.stateNode); + }, + commitPlacement: function(finishedWork) { + a: { + for (var parent = finishedWork["return"]; null !== parent; ) { + if (isHostParent(parent)) { + var parentFiber = parent; + break a; + } + parent = parent["return"]; + } + invariant( + !1, + "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." + ); + parentFiber = void 0; + } + var isContainer = (parent = void 0); + switch (parentFiber.tag) { + case 5: + parent = parentFiber.stateNode; + isContainer = !1; + break; + case 3: + parent = parentFiber.stateNode.containerInfo; + isContainer = !0; + break; + case 4: + parent = parentFiber.stateNode.containerInfo; + isContainer = !0; + break; + default: + invariant( + !1, + "Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue." + ); + } + parentFiber.effectTag & 16 && + (resetTextContent(parent), (parentFiber.effectTag &= -17)); + a: b: for (parentFiber = finishedWork; ; ) { + for (; null === parentFiber.sibling; ) { + if ( + null === parentFiber["return"] || + isHostParent(parentFiber["return"]) + ) { + parentFiber = null; + break a; + } + parentFiber = parentFiber["return"]; + } + parentFiber.sibling["return"] = parentFiber["return"]; + for ( + parentFiber = parentFiber.sibling; + 5 !== parentFiber.tag && 6 !== parentFiber.tag; + + ) { + if (parentFiber.effectTag & 2) continue b; + if (null === parentFiber.child || 4 === parentFiber.tag) continue b; + else + (parentFiber.child["return"] = parentFiber), + (parentFiber = parentFiber.child); + } + if (!(parentFiber.effectTag & 2)) { + parentFiber = parentFiber.stateNode; + break a; + } + } + for (var node = finishedWork; ; ) { + if (5 === node.tag || 6 === node.tag) + parentFiber + ? isContainer + ? insertInContainerBefore(parent, node.stateNode, parentFiber) + : insertBefore(parent, node.stateNode, parentFiber) + : isContainer + ? appendChildToContainer(parent, node.stateNode) + : appendChild(parent, node.stateNode); + else if (4 !== node.tag && null !== node.child) { + node.child["return"] = node; + node = node.child; + continue; + } + if (node === finishedWork) break; + for (; null === node.sibling; ) { + if (null === node["return"] || node["return"] === finishedWork) + return; + node = node["return"]; + } + node.sibling["return"] = node["return"]; + node = node.sibling; + } + }, + commitDeletion: function(current) { + unmountHostComponents(current); + current["return"] = null; + current.child = null; + current.alternate && + ((current.alternate.child = null), + (current.alternate["return"] = null)); + }, + commitWork: function(current, finishedWork) { + switch (finishedWork.tag) { + case 2: + break; + case 5: + var _instance8 = finishedWork.stateNode; + if (null != _instance8) { + var newProps = finishedWork.memoizedProps; + current = null !== current ? current.memoizedProps : newProps; + var type = finishedWork.type, + updatePayload = finishedWork.updateQueue; + finishedWork.updateQueue = null; + null !== updatePayload && + commitUpdate( + _instance8, + updatePayload, + type, + current, + newProps, + finishedWork + ); + } + break; + case 6: + invariant( + null !== finishedWork.stateNode, + "This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue." + ); + _instance8 = finishedWork.memoizedProps; + commitTextUpdate( + finishedWork.stateNode, + null !== current ? current.memoizedProps : _instance8, + _instance8 + ); + break; + case 3: + break; + default: + invariant( + !1, + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); + } + }, + commitLifeCycles: function(finishedRoot, current, finishedWork) { + switch (finishedWork.tag) { + case 2: + finishedRoot = finishedWork.stateNode; + if (finishedWork.effectTag & 4) + if (null === current) + (finishedRoot.props = finishedWork.memoizedProps), + (finishedRoot.state = finishedWork.memoizedState), + finishedRoot.componentDidMount(); + else { + var prevProps = current.memoizedProps; + current = current.memoizedState; + finishedRoot.props = finishedWork.memoizedProps; + finishedRoot.state = finishedWork.memoizedState; + finishedRoot.componentDidUpdate( + prevProps, + current, + finishedRoot.__reactInternalSnapshotBeforeUpdate + ); + } + finishedWork = finishedWork.updateQueue; + null !== finishedWork && commitCallbacks(finishedWork, finishedRoot); + break; + case 3: + current = finishedWork.updateQueue; + if (null !== current) { + finishedRoot = null; + if (null !== finishedWork.child) + switch (finishedWork.child.tag) { + case 5: + finishedRoot = getPublicInstance( + finishedWork.child.stateNode + ); + break; + case 2: + finishedRoot = finishedWork.child.stateNode; + } + commitCallbacks(current, finishedRoot); + } + break; + case 5: + finishedRoot = finishedWork.stateNode; + null === current && + finishedWork.effectTag & 4 && + commitMount( + finishedRoot, + finishedWork.type, + finishedWork.memoizedProps, + finishedWork + ); + break; + case 6: + break; + case 4: + break; + default: + invariant( + !1, + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); + } + }, + commitErrorLogging: function(finishedWork, onUncaughtError) { + switch (finishedWork.tag) { + case 2: + var ctor = finishedWork.type; + onUncaughtError = finishedWork.stateNode; + var updateQueue = finishedWork.updateQueue; + invariant( + null !== updateQueue && null !== updateQueue.capturedValues, + "An error logging effect should not have been scheduled if no errors were captured. This error is likely caused by a bug in React. Please file an issue." + ); + var capturedErrors = updateQueue.capturedValues; + updateQueue.capturedValues = null; + "function" !== typeof ctor.getDerivedStateFromCatch && + markLegacyErrorBoundaryAsFailed(onUncaughtError); + onUncaughtError.props = finishedWork.memoizedProps; + onUncaughtError.state = finishedWork.memoizedState; + for (ctor = 0; ctor < capturedErrors.length; ctor++) { + updateQueue = capturedErrors[ctor]; + var _error = updateQueue.value, + stack = updateQueue.stack; + logError(finishedWork, updateQueue); + onUncaughtError.componentDidCatch(_error, { + componentStack: null !== stack ? stack : "" + }); + } + break; + case 3: + ctor = finishedWork.updateQueue; + invariant( + null !== ctor && null !== ctor.capturedValues, + "An error logging effect should not have been scheduled if no errors were captured. This error is likely caused by a bug in React. Please file an issue." + ); + capturedErrors = ctor.capturedValues; + ctor.capturedValues = null; + for (ctor = 0; ctor < capturedErrors.length; ctor++) + (updateQueue = capturedErrors[ctor]), + logError(finishedWork, updateQueue), + onUncaughtError(updateQueue.value); + break; + default: + invariant( + !1, + "This unit of work tag cannot capture errors. This error is likely caused by a bug in React. Please file an issue." + ); + } + }, + commitAttachRef: function(finishedWork) { + var ref = finishedWork.ref; + if (null !== ref) { + var _instance6 = finishedWork.stateNode; + switch (finishedWork.tag) { + case 5: + finishedWork = getPublicInstance(_instance6); + break; + default: + finishedWork = _instance6; + } + "function" === typeof ref + ? ref(finishedWork) + : (ref.current = finishedWork); + } + }, + commitDetachRef: function(current) { + current = current.ref; + null !== current && + ("function" === typeof current + ? current(null) + : (current.current = null)); + } }; } var NO_CONTEXT = {}; @@ -4602,7 +4536,7 @@ function ReactFiberHydrationContext(config) { var fiber = new FiberNode(5, null, null, 0); fiber.type = "DELETED"; fiber.stateNode = instance; - fiber.return = returnFiber; + fiber["return"] = returnFiber; fiber.effectTag = 8; null !== returnFiber.lastEffect ? ((returnFiber.lastEffect.nextEffect = fiber), @@ -4634,11 +4568,11 @@ function ReactFiberHydrationContext(config) { } function popToNextHostParent(fiber) { for ( - fiber = fiber.return; + fiber = fiber["return"]; null !== fiber && 5 !== fiber.tag && 3 !== fiber.tag; ) - fiber = fiber.return; + fiber = fiber["return"]; hydrationParentFiber = fiber; } var shouldSetTextContent = config.shouldSetTextContent; @@ -4872,7 +4806,7 @@ function ReactFiberLegacyContext(stack) { ) { if (isContextProvider(fiber)) return fiber.stateNode.__reactInternalMemoizedMergedChildContext; - fiber = fiber.return; + fiber = fiber["return"]; invariant( fiber, "Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue." @@ -4939,12 +4873,12 @@ function ReactFiberScheduler(config) { function resetStack() { if (null !== nextUnitOfWork) for ( - var interruptedWork = nextUnitOfWork.return; + var interruptedWork = nextUnitOfWork["return"]; null !== interruptedWork; ) unwindInterruptedWork(interruptedWork), - (interruptedWork = interruptedWork.return); + (interruptedWork = interruptedWork["return"]); nextRoot = null; nextRenderExpirationTime = 0; nextUnitOfWork = null; @@ -4956,71 +4890,74 @@ function ReactFiberScheduler(config) { legacyErrorBoundariesThatAlreadyFailed.has(instance) ); } - function markLegacyErrorBoundaryAsFailed(instance) { - null === legacyErrorBoundariesThatAlreadyFailed - ? (legacyErrorBoundariesThatAlreadyFailed = new Set([instance])) - : legacyErrorBoundariesThatAlreadyFailed.add(instance); - } - function completeUnitOfWork(workInProgress) { + function completeUnitOfWork(workInProgress$jscomp$0) { for (;;) { - var current = workInProgress.alternate, - returnFiber = workInProgress.return, - siblingFiber = workInProgress.sibling; - if (0 === (workInProgress.effectTag & 512)) { + var current = workInProgress$jscomp$0.alternate, + returnFiber = workInProgress$jscomp$0["return"], + siblingFiber = workInProgress$jscomp$0.sibling; + if (0 === (workInProgress$jscomp$0.effectTag & 512)) { current = completeWork( current, - workInProgress, + workInProgress$jscomp$0, nextRenderExpirationTime ); + var workInProgress = workInProgress$jscomp$0; if ( 1073741823 === nextRenderExpirationTime || 1073741823 !== workInProgress.expirationTime ) { - var newExpirationTime = 0; - switch (workInProgress.tag) { + b: switch (workInProgress.tag) { case 3: case 2: - var updateQueue = workInProgress.updateQueue; - null !== updateQueue && - (newExpirationTime = updateQueue.expirationTime); + var newExpirationTime = workInProgress.updateQueue; + newExpirationTime = + null === newExpirationTime + ? 0 + : newExpirationTime.expirationTime; + break b; + default: + newExpirationTime = 0; } - for (updateQueue = workInProgress.child; null !== updateQueue; ) - 0 !== updateQueue.expirationTime && + for (var child = workInProgress.child; null !== child; ) + 0 !== child.expirationTime && (0 === newExpirationTime || - newExpirationTime > updateQueue.expirationTime) && - (newExpirationTime = updateQueue.expirationTime), - (updateQueue = updateQueue.sibling); + newExpirationTime > child.expirationTime) && + (newExpirationTime = child.expirationTime), + (child = child.sibling); workInProgress.expirationTime = newExpirationTime; } if (null !== current) return current; null !== returnFiber && 0 === (returnFiber.effectTag & 512) && (null === returnFiber.firstEffect && - (returnFiber.firstEffect = workInProgress.firstEffect), - null !== workInProgress.lastEffect && + (returnFiber.firstEffect = workInProgress$jscomp$0.firstEffect), + null !== workInProgress$jscomp$0.lastEffect && (null !== returnFiber.lastEffect && - (returnFiber.lastEffect.nextEffect = workInProgress.firstEffect), - (returnFiber.lastEffect = workInProgress.lastEffect)), - 1 < workInProgress.effectTag && + (returnFiber.lastEffect.nextEffect = + workInProgress$jscomp$0.firstEffect), + (returnFiber.lastEffect = workInProgress$jscomp$0.lastEffect)), + 1 < workInProgress$jscomp$0.effectTag && (null !== returnFiber.lastEffect - ? (returnFiber.lastEffect.nextEffect = workInProgress) - : (returnFiber.firstEffect = workInProgress), - (returnFiber.lastEffect = workInProgress))); + ? (returnFiber.lastEffect.nextEffect = workInProgress$jscomp$0) + : (returnFiber.firstEffect = workInProgress$jscomp$0), + (returnFiber.lastEffect = workInProgress$jscomp$0))); if (null !== siblingFiber) return siblingFiber; - if (null !== returnFiber) workInProgress = returnFiber; + if (null !== returnFiber) workInProgress$jscomp$0 = returnFiber; else { isRootReadyForCommit = !0; break; } } else { - workInProgress = unwindWork(workInProgress); - if (null !== workInProgress) - return (workInProgress.effectTag &= 511), workInProgress; + workInProgress$jscomp$0 = unwindWork(workInProgress$jscomp$0); + if (null !== workInProgress$jscomp$0) + return ( + (workInProgress$jscomp$0.effectTag &= 2559), workInProgress$jscomp$0 + ); null !== returnFiber && ((returnFiber.firstEffect = returnFiber.lastEffect = null), (returnFiber.effectTag |= 512)); if (null !== siblingFiber) return siblingFiber; - if (null !== returnFiber) workInProgress = returnFiber; + if (null !== returnFiber) workInProgress$jscomp$0 = returnFiber; else break; } } @@ -5072,18 +5009,13 @@ function ReactFiberScheduler(config) { break; } isAsync = nextUnitOfWork; - var returnFiber = isAsync.return; + var returnFiber = isAsync["return"]; if (null === returnFiber) { didFatal = !0; onUncaughtError(thrownValue); break; } - throwException( - returnFiber, - isAsync, - thrownValue, - nextRenderExpirationTime - ); + throwException(returnFiber, isAsync, thrownValue); nextUnitOfWork = completeUnitOfWork(isAsync); } break; @@ -5100,61 +5032,55 @@ function ReactFiberScheduler(config) { "Expired work should have completed. This error is likely caused by a bug in React. Please file an issue." ); } - function onCommitPhaseError(fiber, error) { - var JSCompiler_inline_result; + function scheduleCapture(sourceFiber, boundaryFiber, value, expirationTime) { + sourceFiber = { + value: value, + source: sourceFiber, + stack: getStackAddendumByWorkInProgressFiber(sourceFiber) + }; + insertUpdateIntoFiber(boundaryFiber, { + expirationTime: expirationTime, + partialState: null, + callback: null, + isReplace: !1, + isForced: !1, + capturedValue: sourceFiber, + next: null + }); + scheduleWork(boundaryFiber, expirationTime); + } + function onCommitPhaseError(fiber$jscomp$0, error) { a: { invariant( !isWorking || isCommitting, "dispatch: Cannot dispatch during the render phase." ); - for ( - JSCompiler_inline_result = fiber.return; - null !== JSCompiler_inline_result; - - ) { - switch (JSCompiler_inline_result.tag) { + for (var fiber = fiber$jscomp$0["return"]; null !== fiber; ) { + switch (fiber.tag) { case 2: - var instance = JSCompiler_inline_result.stateNode; + var instance = fiber.stateNode; if ( - "function" === - typeof JSCompiler_inline_result.type.getDerivedStateFromCatch || + "function" === typeof fiber.type.getDerivedStateFromCatch || ("function" === typeof instance.componentDidCatch && !isAlreadyFailedLegacyErrorBoundary(instance)) ) { - fiber = createCapturedValue(error, fiber); - fiber = createClassErrorUpdate( - JSCompiler_inline_result, - fiber, - 1 - ); - enqueueUpdate(JSCompiler_inline_result, fiber, 1); - scheduleWork(JSCompiler_inline_result, 1); - JSCompiler_inline_result = void 0; + scheduleCapture(fiber$jscomp$0, fiber, error, 1); + fiber$jscomp$0 = void 0; break a; } break; case 3: - fiber = createCapturedValue(error, fiber); - fiber = createRootErrorUpdate(JSCompiler_inline_result, fiber, 1); - enqueueUpdate(JSCompiler_inline_result, fiber, 1); - scheduleWork(JSCompiler_inline_result, 1); - JSCompiler_inline_result = void 0; + scheduleCapture(fiber$jscomp$0, fiber, error, 1); + fiber$jscomp$0 = void 0; break a; } - JSCompiler_inline_result = JSCompiler_inline_result.return; + fiber = fiber["return"]; } - 3 === fiber.tag && - ((JSCompiler_inline_result = createCapturedValue(error, fiber)), - (JSCompiler_inline_result = createRootErrorUpdate( - fiber, - JSCompiler_inline_result, - 1 - )), - enqueueUpdate(fiber, JSCompiler_inline_result, 1), - scheduleWork(fiber, 1)); - JSCompiler_inline_result = void 0; + 3 === fiber$jscomp$0.tag && + scheduleCapture(fiber$jscomp$0, fiber$jscomp$0, error, 1); + fiber$jscomp$0 = void 0; } - return JSCompiler_inline_result; + return fiber$jscomp$0; } function computeExpirationForFiber(fiber) { fiber = @@ -5182,7 +5108,7 @@ function ReactFiberScheduler(config) { (0 === fiber.alternate.expirationTime || fiber.alternate.expirationTime > expirationTime) && (fiber.alternate.expirationTime = expirationTime); - if (null === fiber.return) + if (null === fiber["return"]) if (3 === fiber.tag) { var root = fiber.stateNode; !isWorking && @@ -5200,7 +5126,7 @@ function ReactFiberScheduler(config) { expirationTime = void 0; break a; } - fiber = fiber.return; + fiber = fiber["return"]; } expirationTime = void 0; } @@ -5440,7 +5366,7 @@ function ReactFiberScheduler(config) { error = void 0; try { for (; null !== nextEffect; ) - nextEffect.effectTag & 256 && + nextEffect.effectTag & 2048 && commitBeforeMutationLifeCycles(nextEffect.alternate, nextEffect), (nextEffect = nextEffect.nextEffect); } catch (e) { @@ -5516,6 +5442,8 @@ function ReactFiberScheduler(config) { didError, error ); + effectTag$jscomp$0 & 256 && + commitErrorLogging(nextEffect, onUncaughtError); effectTag$jscomp$0 & 128 && commitAttachRef(nextEffect); var next = nextEffect.nextEffect; nextEffect.nextEffect = null; @@ -5578,21 +5506,21 @@ function ReactFiberScheduler(config) { legacyContext, stack, scheduleWork, - markLegacyErrorBoundaryAsFailed, - isAlreadyFailedLegacyErrorBoundary, - onUncaughtError + isAlreadyFailedLegacyErrorBoundary ); var throwException = hostContext.throwException, unwindWork = hostContext.unwindWork, - unwindInterruptedWork = hostContext.unwindInterruptedWork, - createRootErrorUpdate = hostContext.createRootErrorUpdate, - createClassErrorUpdate = hostContext.createClassErrorUpdate; + unwindInterruptedWork = hostContext.unwindInterruptedWork; hostContext = ReactFiberCommitWork( config, onCommitPhaseError, scheduleWork, computeExpirationForFiber, - markLegacyErrorBoundaryAsFailed, + function(instance) { + null === legacyErrorBoundariesThatAlreadyFailed + ? (legacyErrorBoundariesThatAlreadyFailed = new Set([instance])) + : legacyErrorBoundariesThatAlreadyFailed.add(instance); + }, recalculateCurrentTime ); var commitBeforeMutationLifeCycles = @@ -5602,6 +5530,7 @@ function ReactFiberScheduler(config) { commitDeletion = hostContext.commitDeletion, commitWork = hostContext.commitWork, commitLifeCycles = hostContext.commitLifeCycles, + commitErrorLogging = hostContext.commitErrorLogging, commitAttachRef = hostContext.commitAttachRef, commitDetachRef = hostContext.commitDetachRef, now = config.now, @@ -5769,11 +5698,15 @@ function ReactFiberReconciler$1(config) { ? (container.context = parentComponent) : (container.pendingContext = parentComponent); container = callback; - callback = createUpdate(expirationTime); - callback.payload = { element: element }; - container = void 0 === container ? null : container; - null !== container && (callback.callback = container); - enqueueUpdate(currentTime, callback, expirationTime); + insertUpdateIntoFiber(currentTime, { + expirationTime: expirationTime, + partialState: { element: element }, + callback: void 0 === container ? null : container, + isReplace: !1, + isForced: !1, + capturedValue: null, + next: null + }); scheduleWork(currentTime, expirationTime); return expirationTime; } @@ -5894,8 +5827,8 @@ var ReactFiberReconciler$2 = Object.freeze({ default: ReactFiberReconciler$1 }), ReactFiberReconciler$3 = (ReactFiberReconciler$2 && ReactFiberReconciler$1) || ReactFiberReconciler$2, - reactReconciler = ReactFiberReconciler$3.default - ? ReactFiberReconciler$3.default + reactReconciler = ReactFiberReconciler$3["default"] + ? ReactFiberReconciler$3["default"] : ReactFiberReconciler$3, ReactNativeFiberHostComponent = (function() { function ReactNativeFiberHostComponent(tag, viewConfig) { @@ -6286,7 +6219,7 @@ var roots = new Map(), var root = roots.get(containerTag); root && NativeRenderer.updateContainer(null, root, null, function() { - roots.delete(containerTag); + roots["delete"](containerTag); }); }, unmountComponentAtNodeAndRemoveContainer: function(containerTag) { @@ -6372,6 +6305,6 @@ NativeRenderer.injectIntoDevTools({ var ReactNativeRenderer$2 = Object.freeze({ default: ReactNativeRenderer }), ReactNativeRenderer$3 = (ReactNativeRenderer$2 && ReactNativeRenderer) || ReactNativeRenderer$2; -module.exports = ReactNativeRenderer$3.default - ? ReactNativeRenderer$3.default +module.exports = ReactNativeRenderer$3["default"] + ? ReactNativeRenderer$3["default"] : ReactNativeRenderer$3; diff --git a/Libraries/Renderer/shims/NativeMethodsMixin.js b/Libraries/Renderer/shims/NativeMethodsMixin.js index cd0e673b3bf..7acdf99bbd3 100644 --- a/Libraries/Renderer/shims/NativeMethodsMixin.js +++ b/Libraries/Renderer/shims/NativeMethodsMixin.js @@ -4,7 +4,6 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @providesModule NativeMethodsMixin * @flow */ diff --git a/Libraries/Renderer/shims/ReactDebugTool.js b/Libraries/Renderer/shims/ReactDebugTool.js index e45af4fb099..8ea7ba5c143 100644 --- a/Libraries/Renderer/shims/ReactDebugTool.js +++ b/Libraries/Renderer/shims/ReactDebugTool.js @@ -4,7 +4,6 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @providesModule ReactDebugTool */ 'use strict'; diff --git a/Libraries/Renderer/shims/ReactFabric.js b/Libraries/Renderer/shims/ReactFabric.js index 4162ca62fef..8dce288d28a 100644 --- a/Libraries/Renderer/shims/ReactFabric.js +++ b/Libraries/Renderer/shims/ReactFabric.js @@ -4,7 +4,6 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @providesModule ReactFabric * @flow */ 'use strict'; diff --git a/Libraries/Renderer/shims/ReactNative.js b/Libraries/Renderer/shims/ReactNative.js index a648cafbc30..43c5002e05f 100644 --- a/Libraries/Renderer/shims/ReactNative.js +++ b/Libraries/Renderer/shims/ReactNative.js @@ -4,7 +4,6 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @providesModule ReactNative * @flow */ 'use strict'; diff --git a/Libraries/Renderer/shims/ReactNativeComponentTree.js b/Libraries/Renderer/shims/ReactNativeComponentTree.js index 30ec5257f42..8e8ce6ae06c 100644 --- a/Libraries/Renderer/shims/ReactNativeComponentTree.js +++ b/Libraries/Renderer/shims/ReactNativeComponentTree.js @@ -4,7 +4,6 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @providesModule ReactNativeComponentTree * @flow */ diff --git a/Libraries/Renderer/shims/ReactNativeTypes.js b/Libraries/Renderer/shims/ReactNativeTypes.js index bf941197393..485ce162ecc 100644 --- a/Libraries/Renderer/shims/ReactNativeTypes.js +++ b/Libraries/Renderer/shims/ReactNativeTypes.js @@ -5,7 +5,6 @@ * LICENSE file in the root directory of this source tree. * * @flow - * @providesModule ReactNativeTypes */ export type MeasureOnSuccessCallback = ( diff --git a/Libraries/Renderer/shims/ReactNativeViewConfigRegistry.js b/Libraries/Renderer/shims/ReactNativeViewConfigRegistry.js index ffb0fa213f3..c8ed940a860 100644 --- a/Libraries/Renderer/shims/ReactNativeViewConfigRegistry.js +++ b/Libraries/Renderer/shims/ReactNativeViewConfigRegistry.js @@ -4,7 +4,6 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @providesModule ReactNativeViewConfigRegistry * @flow */ 'use strict'; diff --git a/Libraries/Renderer/shims/ReactPerf.js b/Libraries/Renderer/shims/ReactPerf.js index bb6777fff0b..e94c87501c7 100644 --- a/Libraries/Renderer/shims/ReactPerf.js +++ b/Libraries/Renderer/shims/ReactPerf.js @@ -4,7 +4,6 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @providesModule ReactPerf */ 'use strict'; diff --git a/Libraries/Renderer/shims/ReactTypes.js b/Libraries/Renderer/shims/ReactTypes.js index 689ed18bf95..747a6c07b6f 100644 --- a/Libraries/Renderer/shims/ReactTypes.js +++ b/Libraries/Renderer/shims/ReactTypes.js @@ -5,7 +5,6 @@ * LICENSE file in the root directory of this source tree. * * @flow - * @providesModule ReactTypes */ export type ReactNode = diff --git a/Libraries/Renderer/shims/createReactNativeComponentClass.js b/Libraries/Renderer/shims/createReactNativeComponentClass.js index 1a050e8b3cf..cacaedab88f 100644 --- a/Libraries/Renderer/shims/createReactNativeComponentClass.js +++ b/Libraries/Renderer/shims/createReactNativeComponentClass.js @@ -4,7 +4,6 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @providesModule createReactNativeComponentClass * @flow */