diff --git a/Libraries/Renderer/REVISION b/Libraries/Renderer/REVISION index 7e989de97..fc81a7c7f 100644 --- a/Libraries/Renderer/REVISION +++ b/Libraries/Renderer/REVISION @@ -1 +1 @@ -9d484edc4b64160cb335a23a2cb21667fb2cdf4c \ No newline at end of file +1c2876d5b558b8591feb335d8d7204bc46f7da8a \ No newline at end of file diff --git a/Libraries/Renderer/ReactFabric-dev.js b/Libraries/Renderer/ReactFabric-dev.js index 22c77f2e0..0b7a78516 100644 --- a/Libraries/Renderer/ReactFabric-dev.js +++ b/Libraries/Renderer/ReactFabric-dev.js @@ -509,11 +509,13 @@ var injection$1 = { getNodeFromInstance = Injected.getNodeFromInstance; { - warning( - getNodeFromInstance && getInstanceFromNode, - "EventPluginUtils.injection.injectComponentTree(...): Injected " + - "module is missing getNodeFromInstance or getInstanceFromNode." - ); + !(getNodeFromInstance && getInstanceFromNode) + ? warning( + false, + "EventPluginUtils.injection.injectComponentTree(...): Injected " + + "module is missing getNodeFromInstance or getInstanceFromNode." + ) + : void 0; } } }; @@ -549,10 +551,9 @@ var validateEventDispatches = void 0; ? dispatchInstances.length : dispatchInstances ? 1 : 0; - warning( - instancesIsArr === listenersIsArr && instancesLen === listenersLen, - "EventPluginUtils: Invalid `event`." - ); + !(instancesIsArr === listenersIsArr && instancesLen === listenersLen) + ? warning(false, "EventPluginUtils: Invalid `event`.") + : void 0; }; } @@ -939,7 +940,7 @@ function listenerAtPhase(inst, event, propagationPhase) { */ function accumulateDirectionalDispatches(inst, phase, event) { { - warning(inst, "Dispatching inst must not be null"); + !inst ? warning(false, "Dispatching inst must not be null") : void 0; } var listener = listenerAtPhase(inst, event, phase); if (listener) { @@ -1258,13 +1259,15 @@ SyntheticEvent.extend = function(Interface) { !target.constructor.Interface.hasOwnProperty(prop) && shouldBeReleasedProperties.indexOf(prop) === -1 ) { - warning( - didWarnForAddedNewProperty || target.isPersistent(), - "This synthetic event is reused for performance reasons. If you're " + - "seeing this, you're adding a new property in the synthetic event object. " + - "The property is never released. See " + - "https://fb.me/react-event-pooling for more information." - ); + !(didWarnForAddedNewProperty || target.isPersistent()) + ? warning( + false, + "This synthetic event is reused for performance reasons. If you're " + + "seeing this, you're adding a new property in the synthetic event object. " + + "The property is never released. See " + + "https://fb.me/react-event-pooling for more information." + ) + : void 0; didWarnForAddedNewProperty = true; } target[prop] = value; @@ -1311,16 +1314,18 @@ function getPooledWarningPropertyDefinition(propName, getVal) { function warn(action, result) { var warningCondition = false; - warning( - warningCondition, - "This synthetic event is reused for performance reasons. If you're seeing this, " + - "you're %s `%s` on a released/nullified synthetic event. %s. " + - "If you must keep the original synthetic event around, use event.persist(). " + - "See https://fb.me/react-event-pooling for more information.", - action, - propName, - result - ); + !warningCondition + ? warning( + false, + "This synthetic event is reused for performance reasons. If you're seeing this, " + + "you're %s `%s` on a released/nullified synthetic event. %s. " + + "If you must keep the original synthetic event around, use event.persist(). " + + "See https://fb.me/react-event-pooling for more information.", + action, + propName, + result + ) + : void 0; } } @@ -1438,13 +1443,15 @@ function getTouchIdentifier(_ref) { invariant(identifier != null, "Touch object is missing identifier."); { - warning( - identifier <= MAX_TOUCH_BANK, - "Touch identifier %s is greater than maximum supported %s which causes " + - "performance issues backfilling array locations for all of the indices.", - identifier, - MAX_TOUCH_BANK - ); + !(identifier <= MAX_TOUCH_BANK) + ? warning( + false, + "Touch identifier %s is greater than maximum supported %s which causes " + + "performance issues backfilling array locations for all of the indices.", + identifier, + MAX_TOUCH_BANK + ) + : void 0; } return identifier; } @@ -1543,10 +1550,9 @@ var ResponderTouchHistoryStore = { } { var activeRecord = touchBank[touchHistory.indexOfSingleActiveTouch]; - warning( - activeRecord != null && activeRecord.touchActive, - "Cannot find single active touch." - ); + !(activeRecord != null && activeRecord.touchActive) + ? warning(false, "Cannot find single active touch.") + : void 0; } } } @@ -2641,7 +2647,7 @@ var TouchHistoryMath = { // TODO: this is special because it gets imported during build. -var ReactVersion = "16.3.0-alpha.2"; +var ReactVersion = "16.3.1"; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { @@ -3311,15 +3317,17 @@ function findNodeHandle(componentOrHandle) { { var owner = ReactCurrentOwner.current; if (owner !== null && owner.stateNode !== null) { - warning( - owner.stateNode._warnedAboutRefsInRender, - "%s is accessing findNodeHandle inside its render(). " + - "render() should be a pure function of props and state. It should " + - "never access something that requires stale data from the previous " + - "render, such as refs. Move this logic to componentDidMount and " + - "componentDidUpdate instead.", - getComponentName(owner) || "A component" - ); + !owner.stateNode._warnedAboutRefsInRender + ? warning( + false, + "%s is accessing findNodeHandle inside its render(). " + + "render() should be a pure function of props and state. It should " + + "never access something that requires stale data from the previous " + + "render, such as refs. Move this logic to componentDidMount and " + + "componentDidUpdate instead.", + getComponentName(owner) || "A component" + ) + : void 0; owner.stateNode._warnedAboutRefsInRender = true; } @@ -3777,7 +3785,8 @@ var frameDeadline = 0; var frameDeadlineObject = { timeRemaining: function() { return frameDeadline - now(); - } + }, + didTimeout: false }; function setTimeoutCallback() { @@ -3865,9 +3874,10 @@ var Callback = /* */ 32; var DidCapture = /* */ 64; var Ref = /* */ 128; var ErrLog = /* */ 256; +var Snapshot = /* */ 2048; // Union of all host effects -var HostEffectMask = /* */ 511; +var HostEffectMask = /* */ 2559; var Incomplete = /* */ 512; var ShouldCapture = /* */ 1024; @@ -3915,15 +3925,17 @@ function isMounted(component) { if (owner !== null && owner.tag === ClassComponent) { var ownerFiber = owner; var instance = ownerFiber.stateNode; - warning( - instance._warnedAboutRefsInRender, - "%s is accessing isMounted inside its render() function. " + - "render() should be a pure function of props and state. It should " + - "never access something that requires stale data from the previous " + - "render, such as refs. Move this logic to componentDidMount and " + - "componentDidUpdate instead.", - getComponentName(ownerFiber) || "A component" - ); + !instance._warnedAboutRefsInRender + ? warning( + false, + "%s is accessing isMounted inside its render() function. " + + "render() should be a pure function of props and state. It should " + + "never access something that requires stale data from the previous " + + "render, such as refs. Move this logic to componentDidMount and " + + "componentDidUpdate instead.", + getComponentName(ownerFiber) || "A component" + ) + : void 0; instance._warnedAboutRefsInRender = true; } } @@ -4476,6 +4488,47 @@ function createFiberFromPortal(portal, mode, expirationTime) { return fiber; } +// Used for stashing WIP properties to replay failed work in DEV. +function assignFiberPropertiesInDEV(target, source) { + if (target === null) { + // This Fiber's initial properties will always be overwritten. + // We only use a Fiber to ensure the same hidden class so DEV isn't slow. + target = createFiber(IndeterminateComponent, null, null, NoContext); + } + + // This is intentionally written as a list of all properties. + // We tried to use Object.assign() instead but this is called in + // the hottest path, and Object.assign() was too slow: + // https://github.com/facebook/react/issues/12502 + // This code is DEV-only so size is not a concern. + + target.tag = source.tag; + target.key = source.key; + target.type = source.type; + target.stateNode = source.stateNode; + target["return"] = source["return"]; + target.child = source.child; + target.sibling = source.sibling; + target.index = source.index; + target.ref = source.ref; + target.pendingProps = source.pendingProps; + target.memoizedProps = source.memoizedProps; + target.updateQueue = source.updateQueue; + target.memoizedState = source.memoizedState; + target.mode = source.mode; + target.effectTag = source.effectTag; + target.nextEffect = source.nextEffect; + target.firstEffect = source.firstEffect; + target.lastEffect = source.lastEffect; + target.expirationTime = source.expirationTime; + target.alternate = source.alternate; + target._debugID = source._debugID; + target._debugSource = source._debugSource; + target._debugOwner = source._debugOwner; + target._debugIsCurrentlyTiming = source._debugIsCurrentlyTiming; + return target; +} + // TODO: This should be lifted into the renderer. function createFiberRoot(containerInfo, isAsync, hydrate) { @@ -4881,7 +4934,10 @@ var ReactStrictModeWarnings = { ) { pendingComponentWillReceivePropsWarnings.push(fiber); } - if (typeof instance.componentWillUpdate === "function") { + if ( + typeof instance.componentWillUpdate === "function" && + instance.componentWillUpdate.__suppressDeprecationWarning !== true + ) { pendingComponentWillUpdateWarnings.push(fiber); } }; @@ -4954,7 +5010,6 @@ var ReactStrictModeWarnings = { var debugRenderPhaseSideEffects = false; var debugRenderPhaseSideEffectsForStrictMode = false; - var enableUserTimingAPI = true; var enableGetDerivedStateFromCatch = false; var warnAboutDeprecatedLifecycles = false; @@ -5223,13 +5278,15 @@ function startRequestCallbackTimer() { } } -function stopRequestCallbackTimer(didExpire) { +function stopRequestCallbackTimer(didExpire, expirationTime) { if (enableUserTimingAPI) { if (supportsUserTiming) { isWaitingForCallback = false; var warning$$1 = didExpire ? "React was blocked by main thread" : null; endMark( - "(Waiting for async callback...)", + "(Waiting for async callback... will force flush in " + + expirationTime + + " ms)", "(Waiting for async callback...)", warning$$1 ); @@ -5339,7 +5396,7 @@ function startWorkLoopTimer(nextUnitOfWork) { } } -function stopWorkLoopTimer(interruptedBy) { +function stopWorkLoopTimer(interruptedBy, didCompleteRoot) { if (enableUserTimingAPI) { if (!supportsUserTiming) { return; @@ -5357,13 +5414,12 @@ function stopWorkLoopTimer(interruptedBy) { warning$$1 = "There were cascading updates"; } commitCountInCurrentWorkLoop = 0; + var label = didCompleteRoot + ? "(React Tree Reconciliation: Completed Root)" + : "(React Tree Reconciliation: Yielded)"; // Pause any measurements until the next loop. pauseTimers(); - endMark( - "(React Tree Reconciliation)", - "(React Tree Reconciliation)", - warning$$1 - ); + endMark(label, "(React Tree Reconciliation)", warning$$1); } } @@ -5400,6 +5456,31 @@ function stopCommitTimer() { } } +function startCommitSnapshotEffectsTimer() { + if (enableUserTimingAPI) { + if (!supportsUserTiming) { + return; + } + effectCountInCurrentCommit = 0; + beginMark("(Committing Snapshot Effects)"); + } +} + +function stopCommitSnapshotEffectsTimer() { + if (enableUserTimingAPI) { + if (!supportsUserTiming) { + return; + } + var count = effectCountInCurrentCommit; + effectCountInCurrentCommit = 0; + endMark( + "(Committing Snapshot Effects: " + count + " Total)", + "(Committing Snapshot Effects)", + null + ); + } +} + function startCommitHostEffectsTimer() { if (enableUserTimingAPI) { if (!supportsUserTiming) { @@ -5784,23 +5865,26 @@ var isArray = Array.isArray; var didWarnAboutStateAssignmentForComponent = void 0; var didWarnAboutUndefinedDerivedState = void 0; var didWarnAboutUninitializedState = void 0; -var didWarnAboutWillReceivePropsAndDerivedState = void 0; +var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = void 0; +var didWarnAboutLegacyLifecyclesAndDerivedState = void 0; var warnOnInvalidCallback = void 0; { - didWarnAboutStateAssignmentForComponent = {}; - didWarnAboutUndefinedDerivedState = {}; - didWarnAboutUninitializedState = {}; - didWarnAboutWillReceivePropsAndDerivedState = {}; + didWarnAboutStateAssignmentForComponent = new Set(); + didWarnAboutUndefinedDerivedState = new Set(); + didWarnAboutUninitializedState = new Set(); + didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set(); + didWarnAboutLegacyLifecyclesAndDerivedState = new Set(); - var didWarnOnInvalidCallback = {}; + var didWarnOnInvalidCallback = new Set(); warnOnInvalidCallback = function(callback, callerName) { if (callback === null || typeof callback === "function") { return; } var key = callerName + "_" + callback; - if (!didWarnOnInvalidCallback[key]) { + if (!didWarnOnInvalidCallback.has(key)) { + didWarnOnInvalidCallback.add(key); warning( false, "%s(...): Expected the last optional `callback` argument to be a " + @@ -5808,7 +5892,6 @@ var warnOnInvalidCallback = void 0; callerName, callback ); - didWarnOnInvalidCallback[key] = true; } }; @@ -5951,12 +6034,14 @@ var ReactFiberClassComponent = function( stopPhaseTimer(); { - warning( - shouldUpdate !== undefined, - "%s.shouldComponentUpdate(): Returned undefined instead of a " + - "boolean value. Make sure to return true or false.", - getComponentName(workInProgress) || "Unknown" - ); + !(shouldUpdate !== undefined) + ? warning( + false, + "%s.shouldComponentUpdate(): Returned undefined instead of a " + + "boolean value. Make sure to return true or false.", + getComponentName(workInProgress) || "Component" + ) + : void 0; } return shouldUpdate; @@ -5975,7 +6060,7 @@ var ReactFiberClassComponent = function( var instance = workInProgress.stateNode; var type = workInProgress.type; { - var name = getComponentName(workInProgress); + var name = getComponentName(workInProgress) || "Component"; var renderPresent = instance.render; if (!renderPresent) { @@ -6000,47 +6085,57 @@ var ReactFiberClassComponent = function( !instance.getInitialState || instance.getInitialState.isReactClassApproved || instance.state; - warning( - noGetInitialStateOnES6, - "getInitialState was defined on %s, a plain JavaScript class. " + - "This is only supported for classes created using React.createClass. " + - "Did you mean to define a state property instead?", - name - ); + !noGetInitialStateOnES6 + ? warning( + false, + "getInitialState was defined on %s, a plain JavaScript class. " + + "This is only supported for classes created using React.createClass. " + + "Did you mean to define a state property instead?", + name + ) + : void 0; var noGetDefaultPropsOnES6 = !instance.getDefaultProps || instance.getDefaultProps.isReactClassApproved; - warning( - noGetDefaultPropsOnES6, - "getDefaultProps was defined on %s, a plain JavaScript class. " + - "This is only supported for classes created using React.createClass. " + - "Use a static property to define defaultProps instead.", - name - ); + !noGetDefaultPropsOnES6 + ? warning( + false, + "getDefaultProps was defined on %s, a plain JavaScript class. " + + "This is only supported for classes created using React.createClass. " + + "Use a static property to define defaultProps instead.", + name + ) + : void 0; var noInstancePropTypes = !instance.propTypes; - warning( - noInstancePropTypes, - "propTypes was defined as an instance property on %s. Use a static " + - "property to define propTypes instead.", - name - ); + !noInstancePropTypes + ? warning( + false, + "propTypes was defined as an instance property on %s. Use a static " + + "property to define propTypes instead.", + name + ) + : void 0; var noInstanceContextTypes = !instance.contextTypes; - warning( - noInstanceContextTypes, - "contextTypes was defined as an instance property on %s. Use a static " + - "property to define contextTypes instead.", - name - ); + !noInstanceContextTypes + ? warning( + false, + "contextTypes was defined as an instance property on %s. Use a static " + + "property to define contextTypes instead.", + name + ) + : void 0; var noComponentShouldUpdate = typeof instance.componentShouldUpdate !== "function"; - warning( - noComponentShouldUpdate, - "%s has a method called " + - "componentShouldUpdate(). Did you mean shouldComponentUpdate()? " + - "The name is phrased as a question because the function is " + - "expected to return a value.", - name - ); + !noComponentShouldUpdate + ? warning( + false, + "%s has a method called " + + "componentShouldUpdate(). Did you mean shouldComponentUpdate()? " + + "The name is phrased as a question because the function is " + + "expected to return a value.", + name + ) + : void 0; if ( type.prototype && type.prototype.isPureReactComponent && @@ -6056,73 +6151,128 @@ var ReactFiberClassComponent = function( } var noComponentDidUnmount = typeof instance.componentDidUnmount !== "function"; - warning( - noComponentDidUnmount, - "%s has a method called " + - "componentDidUnmount(). But there is no such lifecycle method. " + - "Did you mean componentWillUnmount()?", - name - ); + !noComponentDidUnmount + ? warning( + false, + "%s has a method called " + + "componentDidUnmount(). But there is no such lifecycle method. " + + "Did you mean componentWillUnmount()?", + name + ) + : void 0; var noComponentDidReceiveProps = typeof instance.componentDidReceiveProps !== "function"; - warning( - noComponentDidReceiveProps, - "%s has a method called " + - "componentDidReceiveProps(). But there is no such lifecycle method. " + - "If you meant to update the state in response to changing props, " + - "use componentWillReceiveProps(). If you meant to fetch data or " + - "run side-effects or mutations after React has updated the UI, use componentDidUpdate().", - name - ); + !noComponentDidReceiveProps + ? warning( + false, + "%s has a method called " + + "componentDidReceiveProps(). But there is no such lifecycle method. " + + "If you meant to update the state in response to changing props, " + + "use componentWillReceiveProps(). If you meant to fetch data or " + + "run side-effects or mutations after React has updated the UI, use componentDidUpdate().", + name + ) + : void 0; var noComponentWillRecieveProps = typeof instance.componentWillRecieveProps !== "function"; - warning( - noComponentWillRecieveProps, - "%s has a method called " + - "componentWillRecieveProps(). Did you mean componentWillReceiveProps()?", - name - ); + !noComponentWillRecieveProps + ? warning( + false, + "%s has a method called " + + "componentWillRecieveProps(). Did you mean componentWillReceiveProps()?", + name + ) + : void 0; var noUnsafeComponentWillRecieveProps = typeof instance.UNSAFE_componentWillRecieveProps !== "function"; - warning( - noUnsafeComponentWillRecieveProps, - "%s has a method called " + - "UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?", - name - ); + !noUnsafeComponentWillRecieveProps + ? warning( + false, + "%s has a method called " + + "UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?", + name + ) + : void 0; var hasMutatedProps = instance.props !== workInProgress.pendingProps; - warning( - instance.props === undefined || !hasMutatedProps, - "%s(...): When calling super() in `%s`, make sure to pass " + - "up the same props that your component's constructor was passed.", - name, - name - ); + !(instance.props === undefined || !hasMutatedProps) + ? warning( + false, + "%s(...): When calling super() in `%s`, make sure to pass " + + "up the same props that your component's constructor was passed.", + name, + name + ) + : void 0; var noInstanceDefaultProps = !instance.defaultProps; - warning( - noInstanceDefaultProps, - "Setting defaultProps as an instance property on %s is not supported and will be ignored." + - " Instead, define defaultProps as a static property on %s.", - name, - name - ); - } + !noInstanceDefaultProps + ? warning( + false, + "Setting defaultProps as an instance property on %s is not supported and will be ignored." + + " Instead, define defaultProps as a static property on %s.", + name, + name + ) + : void 0; - var state = instance.state; - if (state && (typeof state !== "object" || isArray(state))) { - warning( - false, - "%s.state: must be set to an object or null", - getComponentName(workInProgress) - ); - } - if (typeof instance.getChildContext === "function") { - warning( - typeof type.childContextTypes === "object", - "%s.getChildContext(): childContextTypes must be defined in order to " + - "use getChildContext().", - getComponentName(workInProgress) - ); + if ( + typeof instance.getSnapshotBeforeUpdate === "function" && + typeof instance.componentDidUpdate !== "function" && + typeof instance.componentDidUpdate !== "function" && + !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(type) + ) { + didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(type); + warning( + false, + "%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). " + + "This component defines getSnapshotBeforeUpdate() only.", + getComponentName(workInProgress) + ); + } + + var noInstanceGetDerivedStateFromProps = + typeof instance.getDerivedStateFromProps !== "function"; + !noInstanceGetDerivedStateFromProps + ? warning( + false, + "%s: getDerivedStateFromProps() is defined as an instance method " + + "and will be ignored. Instead, declare it as a static method.", + name + ) + : void 0; + var noInstanceGetDerivedStateFromCatch = + typeof instance.getDerivedStateFromCatch !== "function"; + !noInstanceGetDerivedStateFromCatch + ? warning( + false, + "%s: getDerivedStateFromCatch() is defined as an instance method " + + "and will be ignored. Instead, declare it as a static method.", + name + ) + : void 0; + var noStaticGetSnapshotBeforeUpdate = + typeof type.getSnapshotBeforeUpdate !== "function"; + !noStaticGetSnapshotBeforeUpdate + ? warning( + false, + "%s: getSnapshotBeforeUpdate() is defined as a static method " + + "and will be ignored. Instead, declare it as an instance method.", + name + ) + : void 0; + var _state = instance.state; + if (_state && (typeof _state !== "object" || isArray(_state))) { + warning(false, "%s.state: must be set to an object or null", name); + } + if (typeof instance.getChildContext === "function") { + !(typeof type.childContextTypes === "object") + ? warning( + false, + "%s.getChildContext(): childContextTypes must be defined in order to " + + "use getChildContext().", + name + ) + : void 0; + } } } @@ -6170,8 +6320,9 @@ var ReactFiberClassComponent = function( typeof ctor.getDerivedStateFromProps === "function" && state === null ) { - var componentName = getComponentName(workInProgress) || "Unknown"; - if (!didWarnAboutUninitializedState[componentName]) { + var componentName = getComponentName(workInProgress) || "Component"; + if (!didWarnAboutUninitializedState.has(componentName)) { + didWarnAboutUninitializedState.add(componentName); warning( false, "%s: Did not properly initialize state during construction. " + @@ -6179,7 +6330,75 @@ var ReactFiberClassComponent = function( componentName, instance.state === null ? "null" : "undefined" ); - didWarnAboutUninitializedState[componentName] = true; + } + } + + // If new component APIs are defined, "unsafe" lifecycles won't be called. + // Warn about these lifecycles if they are present. + // Don't warn about react-lifecycles-compat polyfilled methods though. + if ( + typeof ctor.getDerivedStateFromProps === "function" || + typeof instance.getSnapshotBeforeUpdate === "function" + ) { + var foundWillMountName = null; + var foundWillReceivePropsName = null; + var foundWillUpdateName = null; + if ( + typeof instance.componentWillMount === "function" && + instance.componentWillMount.__suppressDeprecationWarning !== true + ) { + foundWillMountName = "componentWillMount"; + } else if (typeof instance.UNSAFE_componentWillMount === "function") { + foundWillMountName = "UNSAFE_componentWillMount"; + } + if ( + typeof instance.componentWillReceiveProps === "function" && + instance.componentWillReceiveProps.__suppressDeprecationWarning !== + true + ) { + foundWillReceivePropsName = "componentWillReceiveProps"; + } else if ( + typeof instance.UNSAFE_componentWillReceiveProps === "function" + ) { + foundWillReceivePropsName = "UNSAFE_componentWillReceiveProps"; + } + if ( + typeof instance.componentWillUpdate === "function" && + instance.componentWillUpdate.__suppressDeprecationWarning !== true + ) { + foundWillUpdateName = "componentWillUpdate"; + } else if (typeof instance.UNSAFE_componentWillUpdate === "function") { + foundWillUpdateName = "UNSAFE_componentWillUpdate"; + } + if ( + foundWillMountName !== null || + foundWillReceivePropsName !== null || + foundWillUpdateName !== null + ) { + var _componentName = getComponentName(workInProgress) || "Component"; + var newApiName = + typeof ctor.getDerivedStateFromProps === "function" + ? "getDerivedStateFromProps()" + : "getSnapshotBeforeUpdate()"; + if ( + !didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName) + ) { + didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName); + warning( + false, + "Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n" + + "%s uses %s but also contains the following legacy lifecycles:%s%s%s\n\n" + + "The above lifecycles should be removed. Learn more about this warning here:\n" + + "https://fb.me/react-async-component-lifecycle-hooks", + _componentName, + newApiName, + foundWillMountName !== null ? "\n " + foundWillMountName : "", + foundWillReceivePropsName !== null + ? "\n " + foundWillReceivePropsName + : "", + foundWillUpdateName !== null ? "\n " + foundWillUpdateName : "" + ); + } } } } @@ -6189,7 +6408,8 @@ var ReactFiberClassComponent = function( var partialState = callGetDerivedStateFromProps( workInProgress, instance, - props + props, + state ); if (partialState !== null && partialState !== undefined) { @@ -6232,7 +6452,7 @@ var ReactFiberClassComponent = function( "%s.componentWillMount(): Assigning directly to this.state is " + "deprecated (except inside a component's " + "constructor). Use setState instead.", - getComponentName(workInProgress) + getComponentName(workInProgress) || "Component" ); } updater.enqueueReplaceState(instance, instance.state, null); @@ -6258,7 +6478,8 @@ var ReactFiberClassComponent = function( if (instance.state !== oldState) { { var componentName = getComponentName(workInProgress) || "Component"; - if (!didWarnAboutStateAssignmentForComponent[componentName]) { + if (!didWarnAboutStateAssignmentForComponent.has(componentName)) { + didWarnAboutStateAssignmentForComponent.add(componentName); warning( false, "%s.componentWillReceiveProps(): Assigning directly to " + @@ -6266,69 +6487,47 @@ var ReactFiberClassComponent = function( "constructor). Use setState instead.", componentName ); - didWarnAboutStateAssignmentForComponent[componentName] = true; } } updater.enqueueReplaceState(instance, instance.state, null); } } - function callGetDerivedStateFromProps(workInProgress, instance, props) { + function callGetDerivedStateFromProps( + workInProgress, + instance, + nextProps, + prevState + ) { var type = workInProgress.type; if (typeof type.getDerivedStateFromProps === "function") { - { - // Don't warn about react-lifecycles-compat polyfilled components - if ( - (typeof instance.componentWillReceiveProps === "function" && - instance.componentWillReceiveProps.__suppressDeprecationWarning !== - true) || - typeof instance.UNSAFE_componentWillReceiveProps === "function" - ) { - var componentName = getComponentName(workInProgress) || "Unknown"; - if (!didWarnAboutWillReceivePropsAndDerivedState[componentName]) { - warning( - false, - "%s: Defines both componentWillReceiveProps() and static " + - "getDerivedStateFromProps() methods. We recommend using " + - "only getDerivedStateFromProps().", - componentName - ); - didWarnAboutWillReceivePropsAndDerivedState[componentName] = true; - } - } - } - if ( debugRenderPhaseSideEffects || (debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) ) { // Invoke method an extra time to help detect side-effects. - type.getDerivedStateFromProps.call( - null, - props, - workInProgress.memoizedState - ); + type.getDerivedStateFromProps.call(null, nextProps, prevState); } var partialState = type.getDerivedStateFromProps.call( null, - props, - workInProgress.memoizedState + nextProps, + prevState ); { if (partialState === undefined) { - var _componentName = getComponentName(workInProgress) || "Unknown"; - if (!didWarnAboutUndefinedDerivedState[_componentName]) { + 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 + componentName ); - didWarnAboutUndefinedDerivedState[_componentName] = _componentName; } } } @@ -6372,11 +6571,12 @@ var ReactFiberClassComponent = function( } // In order to support react-lifecycles-compat polyfilled components, - // Unsafe lifecycles should not be invoked for any component with the new gDSFP. + // Unsafe lifecycles should not be invoked for components using the new APIs. if ( + typeof ctor.getDerivedStateFromProps !== "function" && + typeof instance.getSnapshotBeforeUpdate !== "function" && (typeof instance.UNSAFE_componentWillMount === "function" || - typeof instance.componentWillMount === "function") && - typeof ctor.getDerivedStateFromProps !== "function" + typeof instance.componentWillMount === "function") ) { callComponentWillMount(workInProgress, instance); // If we had additional state updates during this life-cycle, let's @@ -6409,16 +6609,20 @@ var ReactFiberClassComponent = function( var newUnmaskedContext = getUnmaskedContext(workInProgress); var newContext = getMaskedContext(workInProgress, newUnmaskedContext); + var hasNewLifecycles = + typeof ctor.getDerivedStateFromProps === "function" || + typeof instance.getSnapshotBeforeUpdate === "function"; + // Note: During these life-cycles, instance.props/instance.state are what // ever the previously attempted to render - not the "current". However, // during componentDidUpdate we pass the "current" props. // In order to support react-lifecycles-compat polyfilled components, - // Unsafe lifecycles should not be invoked for any component with the new gDSFP. + // Unsafe lifecycles should not be invoked for components using the new APIs. if ( + !hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === "function" || - typeof instance.componentWillReceiveProps === "function") && - typeof ctor.getDerivedStateFromProps !== "function" + typeof instance.componentWillReceiveProps === "function") ) { if (oldProps !== newProps || oldContext !== newContext) { callComponentWillReceiveProps( @@ -6430,15 +6634,6 @@ var ReactFiberClassComponent = function( } } - var derivedStateFromProps = void 0; - if (oldProps !== newProps) { - derivedStateFromProps = callGetDerivedStateFromProps( - workInProgress, - instance, - newProps - ); - } - // Compute the next state using the memoized state and the update queue. var oldState = workInProgress.memoizedState; // TODO: Previous state can be null. @@ -6475,6 +6670,18 @@ var ReactFiberClassComponent = function( newState = oldState; } + 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, + instance, + newProps, + newState + ); + } + 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. @@ -6483,6 +6690,17 @@ var ReactFiberClassComponent = function( 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, @@ -6492,6 +6710,17 @@ var ReactFiberClassComponent = function( 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 ( @@ -6522,11 +6751,11 @@ var ReactFiberClassComponent = function( if (shouldUpdate) { // In order to support react-lifecycles-compat polyfilled components, - // Unsafe lifecycles should not be invoked for any component with the new gDSFP. + // Unsafe lifecycles should not be invoked for components using the new APIs. if ( + !hasNewLifecycles && (typeof instance.UNSAFE_componentWillMount === "function" || - typeof instance.componentWillMount === "function") && - typeof ctor.getDerivedStateFromProps !== "function" + typeof instance.componentWillMount === "function") ) { startPhaseTimer(workInProgress, "componentWillMount"); if (typeof instance.componentWillMount === "function") { @@ -6574,16 +6803,20 @@ var ReactFiberClassComponent = function( var newUnmaskedContext = getUnmaskedContext(workInProgress); var newContext = getMaskedContext(workInProgress, newUnmaskedContext); + var hasNewLifecycles = + typeof ctor.getDerivedStateFromProps === "function" || + typeof instance.getSnapshotBeforeUpdate === "function"; + // Note: During these life-cycles, instance.props/instance.state are what // ever the previously attempted to render - not the "current". However, // during componentDidUpdate we pass the "current" props. // In order to support react-lifecycles-compat polyfilled components, - // Unsafe lifecycles should not be invoked for any component with the new gDSFP. + // Unsafe lifecycles should not be invoked for components using the new APIs. if ( + !hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === "function" || - typeof instance.componentWillReceiveProps === "function") && - typeof ctor.getDerivedStateFromProps !== "function" + typeof instance.componentWillReceiveProps === "function") ) { if (oldProps !== newProps || oldContext !== newContext) { callComponentWillReceiveProps( @@ -6595,20 +6828,12 @@ var ReactFiberClassComponent = function( } } - var derivedStateFromProps = void 0; - if (oldProps !== newProps) { - derivedStateFromProps = callGetDerivedStateFromProps( - workInProgress, - instance, - newProps - ); - } - // Compute the next state using the memoized state and the update queue. var oldState = workInProgress.memoizedState; // TODO: Previous state can be null. var newState = void 0; var derivedStateFromCatch = void 0; + if (workInProgress.updateQueue !== null) { newState = processUpdateQueue( current, @@ -6640,6 +6865,18 @@ var ReactFiberClassComponent = function( newState = oldState; } + 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, + instance, + newProps, + newState + ); + } + 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. @@ -6648,6 +6885,17 @@ var ReactFiberClassComponent = function( 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, @@ -6657,6 +6905,17 @@ var ReactFiberClassComponent = function( 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 ( @@ -6678,6 +6937,14 @@ var ReactFiberClassComponent = function( workInProgress.effectTag |= Update; } } + if (typeof instance.getSnapshotBeforeUpdate === "function") { + if ( + oldProps !== current.memoizedProps || + oldState !== current.memoizedState + ) { + workInProgress.effectTag |= Snapshot; + } + } return false; } @@ -6692,11 +6959,11 @@ var ReactFiberClassComponent = function( if (shouldUpdate) { // In order to support react-lifecycles-compat polyfilled components, - // Unsafe lifecycles should not be invoked for any component with the new gDSFP. + // Unsafe lifecycles should not be invoked for components using the new APIs. if ( + !hasNewLifecycles && (typeof instance.UNSAFE_componentWillUpdate === "function" || - typeof instance.componentWillUpdate === "function") && - typeof ctor.getDerivedStateFromProps !== "function" + typeof instance.componentWillUpdate === "function") ) { startPhaseTimer(workInProgress, "componentWillUpdate"); if (typeof instance.componentWillUpdate === "function") { @@ -6710,6 +6977,9 @@ var ReactFiberClassComponent = function( if (typeof instance.componentDidUpdate === "function") { workInProgress.effectTag |= Update; } + if (typeof instance.getSnapshotBeforeUpdate === "function") { + workInProgress.effectTag |= Snapshot; + } } else { // If an update was already in progress, we should schedule an Update // effect even though we're bailing out, so that cWU/cDU are called. @@ -6721,6 +6991,14 @@ var ReactFiberClassComponent = function( workInProgress.effectTag |= Update; } } + if (typeof instance.getSnapshotBeforeUpdate === "function") { + if ( + oldProps !== current.memoizedProps || + oldState !== current.memoizedState + ) { + workInProgress.effectTag |= Snapshot; + } + } // If shouldComponentUpdate returned false, we should still update the // memoized props/state to indicate that this work can be reused. @@ -7560,13 +7838,15 @@ function ChildReconciler(shouldTrackSideEffects) { if (typeof newChildrenIterable.entries === "function") { var possibleMap = newChildrenIterable; if (possibleMap.entries === iteratorFn) { - warning( - didWarnAboutMaps, - "Using Maps as children is unsupported and will likely yield " + - "unexpected results. Convert it to a sequence/iterable of keyed " + - "ReactElements instead.%s", - getCurrentFiberStackAddendum$1() - ); + !didWarnAboutMaps + ? warning( + false, + "Using Maps as children is unsupported and will likely yield " + + "unexpected results. Convert it to a sequence/iterable of keyed " + + "ReactElements instead.%s", + getCurrentFiberStackAddendum$1() + ) + : void 0; didWarnAboutMaps = true; } } @@ -8532,7 +8812,8 @@ var ReactFiberBeginWork = function( var partialState = callGetDerivedStateFromProps( workInProgress, value, - props + props, + workInProgress.memoizedState ); if (partialState !== null && partialState !== undefined) { @@ -8565,11 +8846,13 @@ var ReactFiberBeginWork = function( var _Component = workInProgress.type; if (_Component) { - warning( - !_Component.childContextTypes, - "%s(...): childContextTypes cannot be defined on a functional component.", - _Component.displayName || _Component.name || "Component" - ); + !!_Component.childContextTypes + ? warning( + false, + "%s(...): childContextTypes cannot be defined on a functional component.", + _Component.displayName || _Component.name || "Component" + ) + : void 0; } if (workInProgress.ref !== null) { var info = ""; @@ -8788,7 +9071,7 @@ var ReactFiberBeginWork = function( renderExpirationTime ) { var providerType = workInProgress.type; - var context = providerType.context; + var context = providerType._context; var newProps = workInProgress.pendingProps; var oldProps = workInProgress.memoizedProps; @@ -8841,12 +9124,14 @@ var ReactFiberBeginWork = function( ? context._calculateChangedBits(oldValue, newValue) : MAX_SIGNED_31_BIT_INT; { - warning( - (changedBits & MAX_SIGNED_31_BIT_INT) === changedBits, - "calculateChangedBits: Expected the return value to be a " + - "31-bit integer. Instead received: %s", - changedBits - ); + !((changedBits & MAX_SIGNED_31_BIT_INT) === changedBits) + ? warning( + false, + "calculateChangedBits: Expected the return value to be a " + + "31-bit integer. Instead received: %s", + changedBits + ) + : void 0; } changedBits |= 0; @@ -8914,21 +9199,23 @@ var ReactFiberBeginWork = function( changedBits, renderExpirationTime ); - } else if (oldProps !== null && oldProps.children === newProps.children) { - // No change. Bailout early if children are the same. - return bailoutOnAlreadyFinishedWork(current, workInProgress); } + // There is no bailout on `children` equality because we expect people + // to often pass a bound method as a child, but it may reference + // `this.state` or `this.props` (and thus needs to re-render on `setState`). var render = newProps.children; { - warning( - typeof render === "function", - "A context consumer was rendered with multiple children, or a child " + - "that isn't a function. A context consumer expects a single child " + - "that is a function. If you did pass a function, make sure there " + - "is no trailing or leading whitespace around it." - ); + !(typeof render === "function") + ? warning( + false, + "A context consumer was rendered with multiple children, or a child " + + "that isn't a function. A context consumer expects a single child " + + "that is a function. If you did pass a function, make sure there " + + "is no trailing or leading whitespace around it." + ) + : void 0; } var newChildren = render(newValue); @@ -9883,6 +10170,11 @@ var invokeGuardedCallback$3 = ReactErrorUtils.invokeGuardedCallback; var hasCaughtError$1 = ReactErrorUtils.hasCaughtError; var clearCaughtError$1 = ReactErrorUtils.clearCaughtError; +var didWarnAboutUndefinedSnapshotBeforeUpdate = null; +{ + didWarnAboutUndefinedSnapshotBeforeUpdate = new Set(); +} + function logError(boundary, errorInfo) { var source = errorInfo.source; var stack = errorInfo.stack; @@ -9892,21 +10184,19 @@ function logError(boundary, errorInfo) { var capturedError = { componentName: source !== null ? getComponentName(source) : null, - error: errorInfo.value, - errorBoundary: boundary, componentStack: stack !== null ? stack : "", + error: errorInfo.value, + errorBoundary: null, errorBoundaryName: null, errorBoundaryFound: false, willRetry: false }; - if (boundary !== null) { + if (boundary !== null && boundary.tag === ClassComponent) { + capturedError.errorBoundary = boundary.stateNode; capturedError.errorBoundaryName = getComponentName(boundary); - capturedError.errorBoundaryFound = capturedError.willRetry = - boundary.tag === ClassComponent; - } else { - capturedError.errorBoundaryName = null; - capturedError.errorBoundaryFound = capturedError.willRetry = false; + capturedError.errorBoundaryFound = true; + capturedError.willRetry = true; } try { @@ -9975,6 +10265,58 @@ var ReactFiberCommitWork = function( } } + function commitBeforeMutationLifeCycles(current, finishedWork) { + switch (finishedWork.tag) { + case ClassComponent: { + if (finishedWork.effectTag & Snapshot) { + if (current !== null) { + var prevProps = current.memoizedProps; + var prevState = current.memoizedState; + startPhaseTimer(finishedWork, "getSnapshotBeforeUpdate"); + var _instance = finishedWork.stateNode; + _instance.props = finishedWork.memoizedProps; + _instance.state = finishedWork.memoizedState; + var snapshot = _instance.getSnapshotBeforeUpdate( + prevProps, + prevState + ); + { + var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate; + if ( + snapshot === undefined && + !didWarnSet.has(finishedWork.type) + ) { + didWarnSet.add(finishedWork.type); + warning( + false, + "%s.getSnapshotBeforeUpdate(): A snapshot value (or null) " + + "must be returned. You have returned undefined.", + getComponentName(finishedWork) + ); + } + } + _instance.__reactInternalSnapshotBeforeUpdate = snapshot; + stopPhaseTimer(); + } + } + return; + } + case HostRoot: + case HostComponent: + case HostText: + case HostPortal: + // Nothing to do for these component types + return; + default: { + invariant( + false, + "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, @@ -9984,50 +10326,54 @@ var ReactFiberCommitWork = function( ) { switch (finishedWork.tag) { case ClassComponent: { - var _instance = finishedWork.stateNode; + var _instance2 = finishedWork.stateNode; if (finishedWork.effectTag & Update) { if (current === null) { startPhaseTimer(finishedWork, "componentDidMount"); - _instance.props = finishedWork.memoizedProps; - _instance.state = finishedWork.memoizedState; - _instance.componentDidMount(); + _instance2.props = finishedWork.memoizedProps; + _instance2.state = finishedWork.memoizedState; + _instance2.componentDidMount(); stopPhaseTimer(); } else { var prevProps = current.memoizedProps; var prevState = current.memoizedState; startPhaseTimer(finishedWork, "componentDidUpdate"); - _instance.props = finishedWork.memoizedProps; - _instance.state = finishedWork.memoizedState; - _instance.componentDidUpdate(prevProps, prevState); + _instance2.props = finishedWork.memoizedProps; + _instance2.state = finishedWork.memoizedState; + _instance2.componentDidUpdate( + prevProps, + prevState, + _instance2.__reactInternalSnapshotBeforeUpdate + ); stopPhaseTimer(); } } var updateQueue = finishedWork.updateQueue; if (updateQueue !== null) { - commitCallbacks(updateQueue, _instance); + commitCallbacks(updateQueue, _instance2); } return; } case HostRoot: { var _updateQueue = finishedWork.updateQueue; if (_updateQueue !== null) { - var _instance2 = null; + var _instance3 = null; if (finishedWork.child !== null) { switch (finishedWork.child.tag) { case HostComponent: - _instance2 = getPublicInstance(finishedWork.child.stateNode); + _instance3 = getPublicInstance(finishedWork.child.stateNode); break; case ClassComponent: - _instance2 = finishedWork.child.stateNode; + _instance3 = finishedWork.child.stateNode; break; } } - commitCallbacks(_updateQueue, _instance2); + commitCallbacks(_updateQueue, _instance3); } return; } case HostComponent: { - var _instance3 = finishedWork.stateNode; + var _instance4 = finishedWork.stateNode; // Renderers may schedule work to be done after host components are mounted // (eg DOM renderer may schedule auto-focus for inputs and form controls). @@ -10036,7 +10382,7 @@ var ReactFiberCommitWork = function( if (current === null && finishedWork.effectTag & Update) { var type = finishedWork.type; var props = finishedWork.memoizedProps; - commitMount(_instance3, type, props, finishedWork); + commitMount(_instance4, type, props, finishedWork); } return; @@ -10064,7 +10410,7 @@ var ReactFiberCommitWork = function( case ClassComponent: { var ctor = finishedWork.type; - var _instance4 = finishedWork.stateNode; + var _instance5 = finishedWork.stateNode; var updateQueue = finishedWork.updateQueue; invariant( updateQueue !== null && updateQueue.capturedValues !== null, @@ -10081,16 +10427,19 @@ var ReactFiberCommitWork = function( // This gets reset before we yield back to the browser. // TODO: Warn in strict mode if getDerivedStateFromCatch is // not defined. - markLegacyErrorBoundaryAsFailed(_instance4); + markLegacyErrorBoundaryAsFailed(_instance5); } - _instance4.props = finishedWork.memoizedProps; - _instance4.state = finishedWork.memoizedState; + _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); - _instance4.componentDidCatch(_error); + _instance5.componentDidCatch(_error, { + componentStack: stack !== null ? stack : "" + }); } } break; @@ -10123,14 +10472,14 @@ var ReactFiberCommitWork = function( 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); @@ -10174,9 +10523,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; } @@ -10313,6 +10662,7 @@ var ReactFiberCommitWork = function( }, commitLifeCycles: commitLifeCycles, + commitBeforeMutationLifeCycles: commitBeforeMutationLifeCycles, commitErrorLogging: commitErrorLogging, commitAttachRef: commitAttachRef, commitDetachRef: commitDetachRef @@ -10571,8 +10921,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 @@ -10585,7 +10935,7 @@ var ReactFiberCommitWork = function( finishedWork.updateQueue = null; if (updatePayload !== null) { commitUpdate( - _instance7, + _instance8, updatePayload, type, oldProps, @@ -10630,6 +10980,7 @@ var ReactFiberCommitWork = function( if (enableMutatingReconciler) { return { + commitBeforeMutationLifeCycles: commitBeforeMutationLifeCycles, commitResetTextContent: commitResetTextContent, commitPlacement: commitPlacement, commitDeletion: commitDeletion, @@ -10675,12 +11026,19 @@ var ReactFiberHostContext = function(config, stack) { // Push current root instance onto the stack; // This allows us to reset root when portals are popped. push(rootInstanceStackCursor, nextRootInstance, fiber); - - var nextRootContext = getRootHostContext(nextRootInstance); - // Track the context and the Fiber that provided it. // This enables us to pop only Fibers that provide unique contexts. push(contextFiberStackCursor, fiber, fiber); + + // Finally, we need to push the host context to the stack. + // However, we can't just call getRootHostContext() and push it because + // we'd have a different number of entries on the stack depending on + // whether getRootHostContext() throws somewhere in renderer code or not. + // So we push an empty value first. This lets us safely unwind on errors. + push(contextStackCursor, NO_CONTEXT, fiber); + var nextRootContext = getRootHostContext(nextRootInstance); + // Now that we know this function doesn't throw, replace it. + pop(contextStackCursor, fiber); push(contextStackCursor, nextRootContext, fiber); } @@ -11391,7 +11749,7 @@ var ReactFiberNewContext = function(stack) { } function pushProvider(providerFiber) { - var context = providerFiber.type.context; + var context = providerFiber.type._context; push(changedBitsCursor, context._changedBits, providerFiber); push(valueCursor, context._currentValue, providerFiber); @@ -11401,12 +11759,16 @@ var ReactFiberNewContext = function(stack) { context._changedBits = providerFiber.stateNode; { - warning( + !( context._currentRenderer === null || - context._currentRenderer === rendererSigil, - "Detected multiple renderers concurrently rendering the " + - "same context provider. This is currently unsupported." - ); + context._currentRenderer === rendererSigil + ) + ? warning( + false, + "Detected multiple renderers concurrently rendering the " + + "same context provider. This is currently unsupported." + ) + : void 0; context._currentRenderer = rendererSigil; } } @@ -11419,7 +11781,7 @@ var ReactFiberNewContext = function(stack) { pop(valueCursor, providerFiber); pop(changedBitsCursor, providerFiber); - var context = providerFiber.type.context; + var context = providerFiber.type._context; context._currentValue = currentValue; context._changedBits = changedBits; } @@ -11532,17 +11894,19 @@ var warnAboutInvalidUpdates = void 0; var didWarnStateUpdateForUnmountedComponent = {}; warnAboutUpdateOnUnmounted = function(fiber) { + // We show the whole stack but dedupe on the top component's name because + // the problematic code almost always lies inside that component. var componentName = getComponentName(fiber) || "ReactClass"; if (didWarnStateUpdateForUnmountedComponent[componentName]) { return; } warning( false, - "Can only update a mounted or mounting " + - "component. This usually means you called setState, replaceState, " + - "or forceUpdate on an unmounted component. This is a no-op.\n\nPlease " + - "check the code for the %s component.", - componentName + "Can't call setState (or forceUpdate) on an unmounted component. This " + + "is a no-op, but it indicates a memory leak in your application. To " + + "fix, cancel all subscriptions and asynchronous tasks in the " + + "componentWillUnmount method.%s", + getStackAddendumByWorkInProgressFiber(fiber) ); didWarnStateUpdateForUnmountedComponent[componentName] = true; }; @@ -11628,6 +11992,8 @@ var ReactFiberScheduler = function(config) { markLegacyErrorBoundaryAsFailed, recalculateCurrentTime ), + commitBeforeMutationLifeCycles = + _ReactFiberCommitWork.commitBeforeMutationLifeCycles, commitResetTextContent = _ReactFiberCommitWork.commitResetTextContent, commitPlacement = _ReactFiberCommitWork.commitPlacement, commitDeletion = _ReactFiberCommitWork.commitDeletion, @@ -11679,11 +12045,19 @@ var ReactFiberScheduler = function(config) { var stashedWorkInProgressProperties = void 0; var replayUnitOfWork = void 0; + var isReplayingFailedUnitOfWork = void 0; + var originalReplayError = void 0; + var rethrowOriginalError = void 0; if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) { stashedWorkInProgressProperties = null; - replayUnitOfWork = function(failedUnitOfWork, isAsync) { - // Retore the original state of the work-in-progress - Object.assign(failedUnitOfWork, stashedWorkInProgressProperties); + isReplayingFailedUnitOfWork = false; + originalReplayError = null; + replayUnitOfWork = function(failedUnitOfWork, error, isAsync) { + // Restore the original state of the work-in-progress + assignFiberPropertiesInDEV( + failedUnitOfWork, + stashedWorkInProgressProperties + ); switch (failedUnitOfWork.tag) { case HostRoot: popHostContainer(failedUnitOfWork); @@ -11703,14 +12077,22 @@ var ReactFiberScheduler = function(config) { break; } // Replay the begin phase. + isReplayingFailedUnitOfWork = true; + originalReplayError = error; invokeGuardedCallback$2(null, workLoop, null, isAsync); + isReplayingFailedUnitOfWork = false; + originalReplayError = null; if (hasCaughtError()) { clearCaughtError(); } else { - // This should be unreachable because the render phase is - // idempotent + // If the begin phase did not fail the second time, set this pointer + // back to the original value. + nextUnitOfWork = failedUnitOfWork; } }; + rethrowOriginalError = function() { + throw originalReplayError; + }; } function resetStack() { @@ -11742,6 +12124,7 @@ var ReactFiberScheduler = function(config) { recordEffect(); var effectTag = nextEffect.effectTag; + if (effectTag & ContentReset) { commitResetTextContent(nextEffect); } @@ -11799,6 +12182,22 @@ var ReactFiberScheduler = function(config) { } } + function commitBeforeMutationLifecycles() { + while (nextEffect !== null) { + var effectTag = nextEffect.effectTag; + + if (effectTag & Snapshot) { + recordEffect(); + var current = nextEffect.alternate; + commitBeforeMutationLifeCycles(current, nextEffect); + } + + // Don't cleanup effects yet; + // This will be done by commitAllLifeCycles() + nextEffect = nextEffect.nextEffect; + } + } + function commitAllLifeCycles( finishedRoot, currentTime, @@ -11906,16 +12305,14 @@ var ReactFiberScheduler = function(config) { prepareForCommit(root.containerInfo); - // Commit all the side-effects within a tree. We'll do this in two passes. - // The first pass performs all the host insertions, updates, deletions and - // ref unmounts. + // Invoke instances of getSnapshotBeforeUpdate before mutation. nextEffect = firstEffect; - startCommitHostEffectsTimer(); + startCommitSnapshotEffectsTimer(); while (nextEffect !== null) { var didError = false; var error = void 0; { - invokeGuardedCallback$2(null, commitAllHostEffects, null); + invokeGuardedCallback$2(null, commitBeforeMutationLifecycles, null); if (hasCaughtError()) { didError = true; error = clearCaughtError(); @@ -11934,6 +12331,36 @@ var ReactFiberScheduler = function(config) { } } } + stopCommitSnapshotEffectsTimer(); + + // Commit all the side-effects within a tree. We'll do this in two passes. + // The first pass performs all the host insertions, updates, deletions and + // ref unmounts. + nextEffect = firstEffect; + startCommitHostEffectsTimer(); + while (nextEffect !== null) { + var _didError = false; + var _error = void 0; + { + invokeGuardedCallback$2(null, commitAllHostEffects, null); + if (hasCaughtError()) { + _didError = true; + _error = clearCaughtError(); + } + } + if (_didError) { + invariant( + nextEffect !== null, + "Should have next effect. This error is likely caused by a bug " + + "in React. Please file an issue." + ); + onCommitPhaseError(nextEffect, _error); + // Clean-up + if (nextEffect !== null) { + nextEffect = nextEffect.nextEffect; + } + } + } stopCommitHostEffectsTimer(); resetAfterCommit(root.containerInfo); @@ -11951,8 +12378,8 @@ var ReactFiberScheduler = function(config) { nextEffect = firstEffect; startCommitLifeCyclesTimer(); while (nextEffect !== null) { - var _didError = false; - var _error = void 0; + var _didError2 = false; + var _error2 = void 0; { invokeGuardedCallback$2( null, @@ -11963,17 +12390,17 @@ var ReactFiberScheduler = function(config) { committedExpirationTime ); if (hasCaughtError()) { - _didError = true; - _error = clearCaughtError(); + _didError2 = true; + _error2 = clearCaughtError(); } } - if (_didError) { + if (_didError2) { invariant( nextEffect !== null, "Should have next effect. This error is likely caused by a bug " + "in React. Please file an issue." ); - onCommitPhaseError(nextEffect, _error); + onCommitPhaseError(nextEffect, _error2); if (nextEffect !== null) { nextEffect = nextEffect.nextEffect; } @@ -12197,12 +12624,21 @@ var ReactFiberScheduler = function(config) { } if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) { - stashedWorkInProgressProperties = Object.assign({}, workInProgress); + stashedWorkInProgressProperties = assignFiberPropertiesInDEV( + stashedWorkInProgressProperties, + workInProgress + ); } var next = beginWork(current, workInProgress, nextRenderExpirationTime); - { ReactDebugCurrentFiber.resetCurrentFiber(); + if (isReplayingFailedUnitOfWork) { + // Currently replaying a failed unit of work. This should be unreachable, + // because the render phase is meant to be idempotent, and it should + // have thrown again. Since it didn't, rethrow the original error, so + // React's internal stack is not misaligned. + rethrowOriginalError(); + } } if (true && ReactFiberInstrumentation_1.debugTool) { ReactFiberInstrumentation_1.debugTool.onBeginWork(workInProgress); @@ -12276,13 +12712,18 @@ var ReactFiberScheduler = function(config) { if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) { var failedUnitOfWork = nextUnitOfWork; - replayUnitOfWork(failedUnitOfWork, isAsync); + replayUnitOfWork(failedUnitOfWork, thrownValue, isAsync); } var sourceFiber = nextUnitOfWork; var returnFiber = sourceFiber["return"]; if (returnFiber === null) { - // This is a fatal error. + // 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 + // context. This information is needed to avoid a stack mismatch. + // Because we're not sure, treat this as a fatal error. We could track + // which phase it fails in, but doesn't seem worth it. At least + // for now. didFatal = true; onUncaughtError(thrownValue); break; @@ -12294,12 +12735,13 @@ var ReactFiberScheduler = function(config) { } while (true); // We're done performing work. Time to clean up. - stopWorkLoopTimer(interruptedBy); - interruptedBy = null; + var didCompleteRoot = false; isWorking = false; // Yield back to main thread. if (didFatal) { + stopWorkLoopTimer(interruptedBy, didCompleteRoot); + interruptedBy = null; // There was a fatal error. { stack.resetStackAfterFatalErrorInDev(); @@ -12308,12 +12750,17 @@ var ReactFiberScheduler = function(config) { } else if (nextUnitOfWork === null) { // We reached the root. if (isRootReadyForCommit) { + didCompleteRoot = true; + stopWorkLoopTimer(interruptedBy, didCompleteRoot); + interruptedBy = null; // The root successfully completed. It's ready for commit. root.pendingCommitExpirationTime = expirationTime; var finishedWork = root.current.alternate; return finishedWork; } else { // The root did not complete. + stopWorkLoopTimer(interruptedBy, didCompleteRoot); + interruptedBy = null; invariant( false, "Expired work should have completed. This error is likely caused " + @@ -12321,6 +12768,8 @@ var ReactFiberScheduler = function(config) { ); } } else { + stopWorkLoopTimer(interruptedBy, didCompleteRoot); + interruptedBy = null; // There's more work to do, but we ran out of time. Yield back to // the renderer. return null; @@ -12506,7 +12955,15 @@ var ReactFiberScheduler = function(config) { interruptedBy = fiber; resetStack(); } - if (nextRoot !== root || !isWorking) { + if ( + // If we're in the render phase, we don't need to schedule this root + // for an update, because we'll do it before we exit... + !isWorking || + isCommitting || + // ...unless this is a different root than the one we're rendering. + nextRoot !== root + ) { + // Add this root to the root schedule. requestWork(root, expirationTime); } if (nestedUpdateCount > NESTED_UPDATE_LIMIT) { @@ -12766,7 +13223,8 @@ var ReactFiberScheduler = function(config) { if (enableUserTimingAPI && deadline !== null) { var didExpire = nextFlushedExpirationTime < recalculateCurrentTime(); - stopRequestCallbackTimer(didExpire); + var timeout = expirationTimeToMs(nextFlushedExpirationTime); + stopRequestCallbackTimer(didExpire, timeout); } if (isAsync) { @@ -12826,7 +13284,11 @@ var ReactFiberScheduler = function(config) { // Perform work on root as if the given expiration time is the current time. // This has the effect of synchronously flushing all work up to and // including the given time. + nextFlushedRoot = root; + nextFlushedExpirationTime = expirationTime; performWorkOnRoot(root, expirationTime, false); + // Flush any sync work that was scheduled by lifecycles + performSyncWork(); finishRendering(); } @@ -13153,12 +13615,14 @@ var ReactFiberReconciler$1 = function(config) { callback = callback === undefined ? null : callback; { - warning( - callback === null || typeof callback === "function", - "render(...): Expected the last optional `callback` argument to be a " + - "function. Instead received: %s.", - callback - ); + !(callback === null || typeof callback === "function") + ? warning( + false, + "render(...): Expected the last optional `callback` argument to be a " + + "function. Instead received: %s.", + callback + ) + : void 0; } var update = { diff --git a/Libraries/Renderer/ReactFabric-prod.js b/Libraries/Renderer/ReactFabric-prod.js index 08f112c70..c12ebd601 100644 --- a/Libraries/Renderer/ReactFabric-prod.js +++ b/Libraries/Renderer/ReactFabric-prod.js @@ -1494,7 +1494,8 @@ var ReactNativeComponent = (function(_React$Component) { frameDeadlineObject = { timeRemaining: function() { return frameDeadline - now(); - } + }, + didTimeout: !1 }; function setTimeoutCallback() { frameDeadline = now() + 5; @@ -2036,13 +2037,18 @@ function ReactFiberClassComponent( instance.state !== workInProgress && updater.enqueueReplaceState(instance, instance.state, null); } - function callGetDerivedStateFromProps(workInProgress, instance, props) { - instance = workInProgress.type; - if ("function" === typeof instance.getDerivedStateFromProps) - return instance.getDerivedStateFromProps.call( + function callGetDerivedStateFromProps( + workInProgress, + instance, + nextProps, + prevState + ) { + workInProgress = workInProgress.type; + if ("function" === typeof workInProgress.getDerivedStateFromProps) + return workInProgress.getDerivedStateFromProps.call( null, - props, - workInProgress.memoizedState + nextProps, + prevState ); } var cacheContext = legacyContext.cacheContext, @@ -2113,7 +2119,7 @@ function ReactFiberClassComponent( null !== ctor.state && void 0 !== ctor.state ? ctor.state : null; adoptClassInstance(workInProgress, ctor); workInProgress.memoizedState = state; - props = callGetDerivedStateFromProps(workInProgress, ctor, props); + props = callGetDerivedStateFromProps(workInProgress, ctor, props, state); null !== props && void 0 !== props && (workInProgress.memoizedState = Object.assign( @@ -2134,9 +2140,10 @@ function ReactFiberClassComponent( instance.state = workInProgress.memoizedState; instance.refs = emptyObject; instance.context = getMaskedContext(workInProgress, unmaskedContext); - ("function" !== typeof instance.UNSAFE_componentWillMount && - "function" !== typeof instance.componentWillMount) || - "function" === typeof ctor.getDerivedStateFromProps || + "function" === typeof ctor.getDerivedStateFromProps || + "function" === typeof instance.getSnapshotBeforeUpdate || + ("function" !== typeof instance.UNSAFE_componentWillMount && + "function" !== typeof instance.componentWillMount) || ((ctor = instance.state), "function" === typeof instance.componentWillMount && instance.componentWillMount(), @@ -2167,9 +2174,11 @@ function ReactFiberClassComponent( oldContext = instance.context, newUnmaskedContext = getUnmaskedContext(workInProgress); newUnmaskedContext = getMaskedContext(workInProgress, newUnmaskedContext); - ("function" !== typeof instance.UNSAFE_componentWillReceiveProps && - "function" !== typeof instance.componentWillReceiveProps) || + (ctor = "function" === typeof ctor.getDerivedStateFromProps || + "function" === typeof instance.getSnapshotBeforeUpdate) || + ("function" !== typeof instance.UNSAFE_componentWillReceiveProps && + "function" !== typeof instance.componentWillReceiveProps) || ((oldProps !== newProps || oldContext !== newUnmaskedContext) && callComponentWillReceiveProps( workInProgress, @@ -2177,14 +2186,7 @@ function ReactFiberClassComponent( newProps, newUnmaskedContext )); - oldContext = void 0; - oldProps !== newProps && - (oldContext = callGetDerivedStateFromProps( - workInProgress, - instance, - newProps - )); - var oldState = workInProgress.memoizedState; + oldContext = workInProgress.memoizedState; renderExpirationTime = null !== workInProgress.updateQueue ? processUpdateQueue( @@ -2195,17 +2197,32 @@ function ReactFiberClassComponent( newProps, renderExpirationTime ) - : oldState; - null !== oldContext && - void 0 !== oldContext && - (renderExpirationTime = + : oldContext; + var derivedStateFromProps = void 0; + oldProps !== newProps && + (derivedStateFromProps = callGetDerivedStateFromProps( + workInProgress, + instance, + newProps, + renderExpirationTime + )); + if (null !== derivedStateFromProps && void 0 !== derivedStateFromProps) { + renderExpirationTime = null === renderExpirationTime || void 0 === renderExpirationTime - ? oldContext - : Object.assign({}, renderExpirationTime, oldContext)); + ? derivedStateFromProps + : Object.assign({}, renderExpirationTime, derivedStateFromProps); + var _updateQueue = workInProgress.updateQueue; + null !== _updateQueue && + (_updateQueue.baseState = Object.assign( + {}, + _updateQueue.baseState, + derivedStateFromProps + )); + } if ( !( oldProps !== newProps || - oldState !== renderExpirationTime || + oldContext !== renderExpirationTime || hasContextChanged() || (null !== workInProgress.updateQueue && workInProgress.updateQueue.hasForceUpdate) @@ -2220,13 +2237,13 @@ function ReactFiberClassComponent( workInProgress, oldProps, newProps, - oldState, + oldContext, renderExpirationTime, newUnmaskedContext )) - ? (("function" !== typeof instance.UNSAFE_componentWillMount && - "function" !== typeof instance.componentWillMount) || - "function" === typeof ctor.getDerivedStateFromProps || + ? (ctor || + ("function" !== typeof instance.UNSAFE_componentWillMount && + "function" !== typeof instance.componentWillMount) || ("function" === typeof instance.componentWillMount && instance.componentWillMount(), "function" === typeof instance.UNSAFE_componentWillMount && @@ -2256,9 +2273,11 @@ function ReactFiberClassComponent( oldContext = instance.context, newUnmaskedContext = getUnmaskedContext(workInProgress); newUnmaskedContext = getMaskedContext(workInProgress, newUnmaskedContext); - ("function" !== typeof instance.UNSAFE_componentWillReceiveProps && - "function" !== typeof instance.componentWillReceiveProps) || + (ctor = "function" === typeof ctor.getDerivedStateFromProps || + "function" === typeof instance.getSnapshotBeforeUpdate) || + ("function" !== typeof instance.UNSAFE_componentWillReceiveProps && + "function" !== typeof instance.componentWillReceiveProps) || ((oldProps !== newProps || oldContext !== newUnmaskedContext) && callComponentWillReceiveProps( workInProgress, @@ -2266,13 +2285,6 @@ function ReactFiberClassComponent( newProps, newUnmaskedContext )); - var derivedStateFromProps = void 0; - oldProps !== newProps && - (derivedStateFromProps = callGetDerivedStateFromProps( - workInProgress, - instance, - newProps - )); oldContext = workInProgress.memoizedState; renderExpirationTime = null !== workInProgress.updateQueue @@ -2285,12 +2297,27 @@ function ReactFiberClassComponent( renderExpirationTime ) : oldContext; - null !== derivedStateFromProps && - void 0 !== derivedStateFromProps && - (renderExpirationTime = + var derivedStateFromProps = void 0; + oldProps !== newProps && + (derivedStateFromProps = callGetDerivedStateFromProps( + workInProgress, + instance, + newProps, + renderExpirationTime + )); + if (null !== derivedStateFromProps && void 0 !== derivedStateFromProps) { + renderExpirationTime = null === renderExpirationTime || void 0 === renderExpirationTime ? derivedStateFromProps - : Object.assign({}, renderExpirationTime, derivedStateFromProps)); + : Object.assign({}, renderExpirationTime, derivedStateFromProps); + var _updateQueue3 = workInProgress.updateQueue; + null !== _updateQueue3 && + (_updateQueue3.baseState = Object.assign( + {}, + _updateQueue3.baseState, + derivedStateFromProps + )); + } if ( !( oldProps !== newProps || @@ -2305,6 +2332,10 @@ function ReactFiberClassComponent( (oldProps === current.memoizedProps && oldContext === current.memoizedState) || (workInProgress.effectTag |= 4), + "function" !== typeof instance.getSnapshotBeforeUpdate || + (oldProps === current.memoizedProps && + oldContext === current.memoizedState) || + (workInProgress.effectTag |= 2048), !1 ); (derivedStateFromProps = checkShouldComponentUpdate( @@ -2315,9 +2346,9 @@ function ReactFiberClassComponent( renderExpirationTime, newUnmaskedContext )) - ? (("function" !== typeof instance.UNSAFE_componentWillUpdate && - "function" !== typeof instance.componentWillUpdate) || - "function" === typeof ctor.getDerivedStateFromProps || + ? (ctor || + ("function" !== typeof instance.UNSAFE_componentWillUpdate && + "function" !== typeof instance.componentWillUpdate) || ("function" === typeof instance.componentWillUpdate && instance.componentWillUpdate( newProps, @@ -2331,11 +2362,17 @@ function ReactFiberClassComponent( newUnmaskedContext )), "function" === typeof instance.componentDidUpdate && - (workInProgress.effectTag |= 4)) + (workInProgress.effectTag |= 4), + "function" === typeof instance.getSnapshotBeforeUpdate && + (workInProgress.effectTag |= 2048)) : ("function" !== typeof instance.componentDidUpdate || (oldProps === current.memoizedProps && oldContext === current.memoizedState) || (workInProgress.effectTag |= 4), + "function" !== typeof instance.getSnapshotBeforeUpdate || + (oldProps === current.memoizedProps && + oldContext === current.memoizedState) || + (workInProgress.effectTag |= 2048), memoizeProps(workInProgress, newProps), memoizeState(workInProgress, renderExpirationTime)); instance.props = newProps; @@ -3181,7 +3218,7 @@ function ReactFiberBeginWork( workInProgress, renderExpirationTime ) { - var context = workInProgress.type.context, + var context = workInProgress.type._context, newProps = workInProgress.pendingProps, oldProps = workInProgress.memoizedProps; if (!hasLegacyContextChanged() && oldProps === newProps) @@ -3347,7 +3384,8 @@ function ReactFiberBeginWork( ((props = callGetDerivedStateFromProps( workInProgress, fn, - props + props, + workInProgress.memoizedState )), null !== props && void 0 !== props && @@ -3618,43 +3656,33 @@ function ReactFiberBeginWork( renderExpirationTime ); case 12: - a: { - fn = workInProgress.type; - unmaskedContext = workInProgress.pendingProps; - updateQueue = workInProgress.memoizedProps; - props = fn._currentValue; - var changedBits = fn._changedBits; - if ( - hasLegacyContextChanged() || - 0 !== changedBits || - updateQueue !== unmaskedContext - ) { - workInProgress.memoizedProps = unmaskedContext; - var observedBits = unmaskedContext.unstable_observedBits; - if (void 0 === observedBits || null === observedBits) - observedBits = 1073741823; - workInProgress.stateNode = observedBits; - if (0 !== (changedBits & observedBits)) - propagateContextChange( - workInProgress, - fn, - changedBits, - renderExpirationTime - ); - else if ( - null !== updateQueue && - updateQueue.children === unmaskedContext.children - ) { - current = bailoutOnAlreadyFinishedWork(current, workInProgress); - break a; - } - renderExpirationTime = unmaskedContext.children; - renderExpirationTime = renderExpirationTime(props); - reconcileChildren(current, workInProgress, renderExpirationTime); - current = workInProgress.child; - } else - current = bailoutOnAlreadyFinishedWork(current, workInProgress); - } + fn = workInProgress.type; + unmaskedContext = workInProgress.pendingProps; + var oldProps = workInProgress.memoizedProps; + props = fn._currentValue; + updateQueue = fn._changedBits; + if ( + hasLegacyContextChanged() || + 0 !== updateQueue || + oldProps !== unmaskedContext + ) { + workInProgress.memoizedProps = unmaskedContext; + oldProps = unmaskedContext.unstable_observedBits; + if (void 0 === oldProps || null === oldProps) oldProps = 1073741823; + workInProgress.stateNode = oldProps; + 0 !== (updateQueue & oldProps) && + propagateContextChange( + workInProgress, + fn, + updateQueue, + renderExpirationTime + ); + renderExpirationTime = unmaskedContext.children; + renderExpirationTime = renderExpirationTime(props); + reconcileChildren(current, workInProgress, renderExpirationTime); + current = workInProgress.child; + } else + current = bailoutOnAlreadyFinishedWork(current, workInProgress); return current; default: invariant( @@ -4105,7 +4133,7 @@ function logError(boundary, errorInfo) { null === errorInfo.stack && getStackAddendumByWorkInProgressFiber(source); null !== source && getComponentName(source); errorInfo = errorInfo.value; - null !== boundary && getComponentName(boundary); + null !== boundary && 2 === boundary.tag && getComponentName(boundary); try { (errorInfo && errorInfo.suppressReactErrorLogging) || console.error(errorInfo); @@ -4131,6 +4159,31 @@ function ReactFiberCommitWork( } 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: @@ -4145,7 +4198,11 @@ function ReactFiberCommitWork( current = current.memoizedState; finishedRoot.props = finishedWork.memoizedProps; finishedRoot.state = finishedWork.memoizedState; - finishedRoot.componentDidUpdate(prevProps, current); + finishedRoot.componentDidUpdate( + prevProps, + current, + finishedRoot.__reactInternalSnapshotBeforeUpdate + ); } finishedWork = finishedWork.updateQueue; null !== finishedWork && commitCallbacks(finishedWork, finishedRoot); @@ -4205,9 +4262,12 @@ function ReactFiberCommitWork( onUncaughtError.state = finishedWork.memoizedState; for (ctor = 0; ctor < capturedErrors.length; ctor++) { updateQueue = capturedErrors[ctor]; - var _error = updateQueue.value; + var _error = updateQueue.value, + stack = updateQueue.stack; logError(finishedWork, updateQueue); - onUncaughtError.componentDidCatch(_error); + onUncaughtError.componentDidCatch(_error, { + componentStack: null !== stack ? stack : "" + }); } break; case 3: @@ -4233,13 +4293,13 @@ function ReactFiberCommitWork( function commitAttachRef(finishedWork) { var ref = finishedWork.ref; if (null !== ref) { - var _instance5 = finishedWork.stateNode; + var _instance6 = finishedWork.stateNode; switch (finishedWork.tag) { case 5: - finishedWork = getPublicInstance(_instance5); + finishedWork = getPublicInstance(_instance6); break; default: - finishedWork = _instance5; + finishedWork = _instance6; } "function" === typeof ref ? ref(finishedWork) @@ -4260,12 +4320,12 @@ function ReactFiberCommitWork( switch (current.tag) { case 2: safelyDetachRef(current); - var _instance6 = current.stateNode; - if ("function" === typeof _instance6.componentWillUnmount) + var _instance7 = current.stateNode; + if ("function" === typeof _instance7.componentWillUnmount) try { - (_instance6.props = current.memoizedProps), - (_instance6.state = current.memoizedState), - _instance6.componentWillUnmount(); + (_instance7.props = current.memoizedProps), + (_instance7.state = current.memoizedState), + _instance7.componentWillUnmount(); } catch (unmountError) { captureError(current, unmountError); } @@ -4343,6 +4403,7 @@ function ReactFiberCommitWork( commitContainer(finishedWork); }, commitLifeCycles: commitLifeCycles, + commitBeforeMutationLifeCycles: commitBeforeMutationLifeCycles, commitErrorLogging: commitErrorLogging, commitAttachRef: commitAttachRef, commitDetachRef: commitDetachRef @@ -4386,8 +4447,10 @@ function ReactFiberHostContext(config, stack) { }, pushHostContainer: function(fiber, nextRootInstance) { push(rootInstanceStackCursor, nextRootInstance, fiber); - nextRootInstance = getRootHostContext(nextRootInstance); push(contextFiberStackCursor, fiber, fiber); + push(contextStackCursor, NO_CONTEXT, fiber); + nextRootInstance = getRootHostContext(nextRootInstance); + pop(contextStackCursor, fiber); push(contextStackCursor, nextRootInstance, fiber); }, pushHostContext: function(fiber) { @@ -4694,7 +4757,7 @@ function ReactFiberNewContext(stack) { changedBitsCursor = createCursor(0); return { pushProvider: function(providerFiber) { - var context = providerFiber.type.context; + var context = providerFiber.type._context; push(changedBitsCursor, context._changedBits, providerFiber); push(valueCursor, context._currentValue, providerFiber); push(providerCursor, providerFiber, providerFiber); @@ -4707,7 +4770,7 @@ function ReactFiberNewContext(stack) { pop(providerCursor, providerFiber); pop(valueCursor, providerFiber); pop(changedBitsCursor, providerFiber); - providerFiber = providerFiber.type.context; + providerFiber = providerFiber.type._context; providerFiber._currentValue = currentValue; providerFiber._changedBits = changedBits; } @@ -4820,7 +4883,7 @@ function ReactFiberScheduler(config) { workInProgress$jscomp$0 = unwindWork(workInProgress$jscomp$0); if (null !== workInProgress$jscomp$0) return ( - (workInProgress$jscomp$0.effectTag &= 511), workInProgress$jscomp$0 + (workInProgress$jscomp$0.effectTag &= 2559), workInProgress$jscomp$0 ); null !== returnFiber && ((returnFiber.firstEffect = returnFiber.lastEffect = null), @@ -4984,7 +5047,7 @@ function ReactFiberScheduler(config) { 0 !== nextRenderExpirationTime && expirationTime < nextRenderExpirationTime && resetStack(); - (nextRoot === root && isWorking) || + (isWorking && !isCommitting && nextRoot === root) || requestWork(root, expirationTime); nestedUpdateCount > NESTED_UPDATE_LIMIT && invariant( @@ -5048,7 +5111,7 @@ function ReactFiberScheduler(config) { (nextFlushedExpirationTime = 1), performWorkOnRoot(root, 1, !1)) : 1 === expirationTime - ? performWork(1, !1, null) + ? performSyncWork() : scheduleCallbackWithExpiration(expirationTime)); } function findHighestPriorityRoot() { @@ -5108,6 +5171,9 @@ function ReactFiberScheduler(config) { function performAsyncWork(dl) { performWork(0, !0, dl); } + function performSyncWork() { + performWork(1, !1, null); + } function performWork(minExpirationTime, isAsync, dl) { deadline = dl; findHighestPriorityRoot(); @@ -5230,6 +5296,25 @@ function ReactFiberScheduler(config) { for (nextEffect = firstEffect; null !== nextEffect; ) { var didError = !1, error = void 0; + try { + for (; null !== nextEffect; ) + nextEffect.effectTag & 2048 && + commitBeforeMutationLifeCycles(nextEffect.alternate, nextEffect), + (nextEffect = nextEffect.nextEffect); + } catch (e) { + (didError = !0), (error = e); + } + didError && + (invariant( + null !== nextEffect, + "Should have next effect. This error is likely caused by a bug in React. Please file an issue." + ), + onCommitPhaseError(nextEffect, error), + null !== nextEffect && (nextEffect = nextEffect.nextEffect)); + } + for (nextEffect = firstEffect; null !== nextEffect; ) { + didError = !1; + error = void 0; try { for (; null !== nextEffect; ) { var effectTag = nextEffect.effectTag; @@ -5370,7 +5455,9 @@ function ReactFiberScheduler(config) { }, recalculateCurrentTime ); - var commitResetTextContent = hostContext.commitResetTextContent, + var commitBeforeMutationLifeCycles = + hostContext.commitBeforeMutationLifeCycles, + commitResetTextContent = hostContext.commitResetTextContent, commitPlacement = hostContext.commitPlacement, commitDeletion = hostContext.commitDeletion, commitWork = hostContext.commitWork, @@ -5425,7 +5512,10 @@ function ReactFiberScheduler(config) { !isRendering, "work.commit(): Cannot commit while already rendering. This likely means you attempted to commit from inside a lifecycle method." ); + nextFlushedRoot = root; + nextFlushedExpirationTime = expirationTime; performWorkOnRoot(root, expirationTime, !1); + performSyncWork(); finishRendering(); }, batchedUpdates: function(fn, a) { @@ -5436,7 +5526,7 @@ function ReactFiberScheduler(config) { } finally { (isBatchingUpdates = previousIsBatchingUpdates) || isRendering || - performWork(1, !1, null); + performSyncWork(); } }, unbatchedUpdates: function(fn, a) { @@ -5460,8 +5550,7 @@ function ReactFiberScheduler(config) { try { return syncUpdates(fn, a); } finally { - (isBatchingUpdates = previousIsBatchingUpdates), - performWork(1, !1, null); + (isBatchingUpdates = previousIsBatchingUpdates), performSyncWork(); } }, flushControlled: function(fn) { @@ -5502,7 +5591,7 @@ function ReactFiberScheduler(config) { (isBatchingInteractiveUpdates = previousIsBatchingInteractiveUpdates), (isBatchingUpdates = previousIsBatchingUpdates) || isRendering || - performWork(1, !1, null); + performSyncWork(); } }, flushInteractiveUpdates: function() { @@ -6003,7 +6092,7 @@ ReactFabricRenderer.injectIntoDevTools({ findFiberByHostInstance: getInstanceFromTag, getInspectorDataForViewTag: getInspectorDataForViewTag, bundleType: 0, - version: "16.3.0-alpha.2", + version: "16.3.1", rendererPackageName: "react-native-renderer" }); var ReactFabric$2 = Object.freeze({ default: ReactFabric }), diff --git a/Libraries/Renderer/ReactNativeRenderer-dev.js b/Libraries/Renderer/ReactNativeRenderer-dev.js index 8ea8bcf85..7fd62f11c 100644 --- a/Libraries/Renderer/ReactNativeRenderer-dev.js +++ b/Libraries/Renderer/ReactNativeRenderer-dev.js @@ -510,11 +510,13 @@ var injection$1 = { getNodeFromInstance = Injected.getNodeFromInstance; { - warning( - getNodeFromInstance && getInstanceFromNode, - "EventPluginUtils.injection.injectComponentTree(...): Injected " + - "module is missing getNodeFromInstance or getInstanceFromNode." - ); + !(getNodeFromInstance && getInstanceFromNode) + ? warning( + false, + "EventPluginUtils.injection.injectComponentTree(...): Injected " + + "module is missing getNodeFromInstance or getInstanceFromNode." + ) + : void 0; } } }; @@ -550,10 +552,9 @@ var validateEventDispatches = void 0; ? dispatchInstances.length : dispatchInstances ? 1 : 0; - warning( - instancesIsArr === listenersIsArr && instancesLen === listenersLen, - "EventPluginUtils: Invalid `event`." - ); + !(instancesIsArr === listenersIsArr && instancesLen === listenersLen) + ? warning(false, "EventPluginUtils: Invalid `event`.") + : void 0; }; } @@ -1094,7 +1095,7 @@ function listenerAtPhase(inst, event, propagationPhase) { */ function accumulateDirectionalDispatches(inst, phase, event) { { - warning(inst, "Dispatching inst must not be null"); + !inst ? warning(false, "Dispatching inst must not be null") : void 0; } var listener = listenerAtPhase(inst, event, phase); if (listener) { @@ -1413,13 +1414,15 @@ SyntheticEvent.extend = function(Interface) { !target.constructor.Interface.hasOwnProperty(prop) && shouldBeReleasedProperties.indexOf(prop) === -1 ) { - warning( - didWarnForAddedNewProperty || target.isPersistent(), - "This synthetic event is reused for performance reasons. If you're " + - "seeing this, you're adding a new property in the synthetic event object. " + - "The property is never released. See " + - "https://fb.me/react-event-pooling for more information." - ); + !(didWarnForAddedNewProperty || target.isPersistent()) + ? warning( + false, + "This synthetic event is reused for performance reasons. If you're " + + "seeing this, you're adding a new property in the synthetic event object. " + + "The property is never released. See " + + "https://fb.me/react-event-pooling for more information." + ) + : void 0; didWarnForAddedNewProperty = true; } target[prop] = value; @@ -1466,16 +1469,18 @@ function getPooledWarningPropertyDefinition(propName, getVal) { function warn(action, result) { var warningCondition = false; - warning( - warningCondition, - "This synthetic event is reused for performance reasons. If you're seeing this, " + - "you're %s `%s` on a released/nullified synthetic event. %s. " + - "If you must keep the original synthetic event around, use event.persist(). " + - "See https://fb.me/react-event-pooling for more information.", - action, - propName, - result - ); + !warningCondition + ? warning( + false, + "This synthetic event is reused for performance reasons. If you're seeing this, " + + "you're %s `%s` on a released/nullified synthetic event. %s. " + + "If you must keep the original synthetic event around, use event.persist(). " + + "See https://fb.me/react-event-pooling for more information.", + action, + propName, + result + ) + : void 0; } } @@ -1593,13 +1598,15 @@ function getTouchIdentifier(_ref) { invariant(identifier != null, "Touch object is missing identifier."); { - warning( - identifier <= MAX_TOUCH_BANK, - "Touch identifier %s is greater than maximum supported %s which causes " + - "performance issues backfilling array locations for all of the indices.", - identifier, - MAX_TOUCH_BANK - ); + !(identifier <= MAX_TOUCH_BANK) + ? warning( + false, + "Touch identifier %s is greater than maximum supported %s which causes " + + "performance issues backfilling array locations for all of the indices.", + identifier, + MAX_TOUCH_BANK + ) + : void 0; } return identifier; } @@ -1698,10 +1705,9 @@ var ResponderTouchHistoryStore = { } { var activeRecord = touchBank[touchHistory.indexOfSingleActiveTouch]; - warning( - activeRecord != null && activeRecord.touchActive, - "Cannot find single active touch." - ); + !(activeRecord != null && activeRecord.touchActive) + ? warning(false, "Cannot find single active touch.") + : void 0; } } } @@ -2987,7 +2993,7 @@ var TouchHistoryMath = { // TODO: this is special because it gets imported during build. -var ReactVersion = "16.3.0-alpha.2"; +var ReactVersion = "16.3.1"; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { @@ -3657,15 +3663,17 @@ function findNodeHandle(componentOrHandle) { { var owner = ReactCurrentOwner.current; if (owner !== null && owner.stateNode !== null) { - warning( - owner.stateNode._warnedAboutRefsInRender, - "%s is accessing findNodeHandle inside its render(). " + - "render() should be a pure function of props and state. It should " + - "never access something that requires stale data from the previous " + - "render, such as refs. Move this logic to componentDidMount and " + - "componentDidUpdate instead.", - getComponentName(owner) || "A component" - ); + !owner.stateNode._warnedAboutRefsInRender + ? warning( + false, + "%s is accessing findNodeHandle inside its render(). " + + "render() should be a pure function of props and state. It should " + + "never access something that requires stale data from the previous " + + "render, such as refs. Move this logic to componentDidMount and " + + "componentDidUpdate instead.", + getComponentName(owner) || "A component" + ) + : void 0; owner.stateNode._warnedAboutRefsInRender = true; } @@ -4120,9 +4128,10 @@ var Callback = /* */ 32; var DidCapture = /* */ 64; var Ref = /* */ 128; var ErrLog = /* */ 256; +var Snapshot = /* */ 2048; // Union of all host effects -var HostEffectMask = /* */ 511; +var HostEffectMask = /* */ 2559; var Incomplete = /* */ 512; var ShouldCapture = /* */ 1024; @@ -4170,15 +4179,17 @@ function isMounted(component) { if (owner !== null && owner.tag === ClassComponent) { var ownerFiber = owner; var instance = ownerFiber.stateNode; - warning( - instance._warnedAboutRefsInRender, - "%s is accessing isMounted inside its render() function. " + - "render() should be a pure function of props and state. It should " + - "never access something that requires stale data from the previous " + - "render, such as refs. Move this logic to componentDidMount and " + - "componentDidUpdate instead.", - getComponentName(ownerFiber) || "A component" - ); + !instance._warnedAboutRefsInRender + ? warning( + false, + "%s is accessing isMounted inside its render() function. " + + "render() should be a pure function of props and state. It should " + + "never access something that requires stale data from the previous " + + "render, such as refs. Move this logic to componentDidMount and " + + "componentDidUpdate instead.", + getComponentName(ownerFiber) || "A component" + ) + : void 0; instance._warnedAboutRefsInRender = true; } } @@ -4731,6 +4742,47 @@ function createFiberFromPortal(portal, mode, expirationTime) { return fiber; } +// Used for stashing WIP properties to replay failed work in DEV. +function assignFiberPropertiesInDEV(target, source) { + if (target === null) { + // This Fiber's initial properties will always be overwritten. + // We only use a Fiber to ensure the same hidden class so DEV isn't slow. + target = createFiber(IndeterminateComponent, null, null, NoContext); + } + + // This is intentionally written as a list of all properties. + // We tried to use Object.assign() instead but this is called in + // the hottest path, and Object.assign() was too slow: + // https://github.com/facebook/react/issues/12502 + // This code is DEV-only so size is not a concern. + + target.tag = source.tag; + target.key = source.key; + target.type = source.type; + target.stateNode = source.stateNode; + target["return"] = source["return"]; + target.child = source.child; + target.sibling = source.sibling; + target.index = source.index; + target.ref = source.ref; + target.pendingProps = source.pendingProps; + target.memoizedProps = source.memoizedProps; + target.updateQueue = source.updateQueue; + target.memoizedState = source.memoizedState; + target.mode = source.mode; + target.effectTag = source.effectTag; + target.nextEffect = source.nextEffect; + target.firstEffect = source.firstEffect; + target.lastEffect = source.lastEffect; + target.expirationTime = source.expirationTime; + target.alternate = source.alternate; + target._debugID = source._debugID; + target._debugSource = source._debugSource; + target._debugOwner = source._debugOwner; + target._debugIsCurrentlyTiming = source._debugIsCurrentlyTiming; + return target; +} + // TODO: This should be lifted into the renderer. function createFiberRoot(containerInfo, isAsync, hydrate) { @@ -5136,7 +5188,10 @@ var ReactStrictModeWarnings = { ) { pendingComponentWillReceivePropsWarnings.push(fiber); } - if (typeof instance.componentWillUpdate === "function") { + if ( + typeof instance.componentWillUpdate === "function" && + instance.componentWillUpdate.__suppressDeprecationWarning !== true + ) { pendingComponentWillUpdateWarnings.push(fiber); } }; @@ -5481,13 +5536,15 @@ function startRequestCallbackTimer() { } } -function stopRequestCallbackTimer(didExpire) { +function stopRequestCallbackTimer(didExpire, expirationTime) { if (enableUserTimingAPI) { if (supportsUserTiming) { isWaitingForCallback = false; var warning$$1 = didExpire ? "React was blocked by main thread" : null; endMark( - "(Waiting for async callback...)", + "(Waiting for async callback... will force flush in " + + expirationTime + + " ms)", "(Waiting for async callback...)", warning$$1 ); @@ -5597,7 +5654,7 @@ function startWorkLoopTimer(nextUnitOfWork) { } } -function stopWorkLoopTimer(interruptedBy) { +function stopWorkLoopTimer(interruptedBy, didCompleteRoot) { if (enableUserTimingAPI) { if (!supportsUserTiming) { return; @@ -5615,13 +5672,12 @@ function stopWorkLoopTimer(interruptedBy) { warning$$1 = "There were cascading updates"; } commitCountInCurrentWorkLoop = 0; + var label = didCompleteRoot + ? "(React Tree Reconciliation: Completed Root)" + : "(React Tree Reconciliation: Yielded)"; // Pause any measurements until the next loop. pauseTimers(); - endMark( - "(React Tree Reconciliation)", - "(React Tree Reconciliation)", - warning$$1 - ); + endMark(label, "(React Tree Reconciliation)", warning$$1); } } @@ -5658,6 +5714,31 @@ function stopCommitTimer() { } } +function startCommitSnapshotEffectsTimer() { + if (enableUserTimingAPI) { + if (!supportsUserTiming) { + return; + } + effectCountInCurrentCommit = 0; + beginMark("(Committing Snapshot Effects)"); + } +} + +function stopCommitSnapshotEffectsTimer() { + if (enableUserTimingAPI) { + if (!supportsUserTiming) { + return; + } + var count = effectCountInCurrentCommit; + effectCountInCurrentCommit = 0; + endMark( + "(Committing Snapshot Effects: " + count + " Total)", + "(Committing Snapshot Effects)", + null + ); + } +} + function startCommitHostEffectsTimer() { if (enableUserTimingAPI) { if (!supportsUserTiming) { @@ -6042,23 +6123,26 @@ var isArray = Array.isArray; var didWarnAboutStateAssignmentForComponent = void 0; var didWarnAboutUndefinedDerivedState = void 0; var didWarnAboutUninitializedState = void 0; -var didWarnAboutWillReceivePropsAndDerivedState = void 0; +var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = void 0; +var didWarnAboutLegacyLifecyclesAndDerivedState = void 0; var warnOnInvalidCallback = void 0; { - didWarnAboutStateAssignmentForComponent = {}; - didWarnAboutUndefinedDerivedState = {}; - didWarnAboutUninitializedState = {}; - didWarnAboutWillReceivePropsAndDerivedState = {}; + didWarnAboutStateAssignmentForComponent = new Set(); + didWarnAboutUndefinedDerivedState = new Set(); + didWarnAboutUninitializedState = new Set(); + didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set(); + didWarnAboutLegacyLifecyclesAndDerivedState = new Set(); - var didWarnOnInvalidCallback = {}; + var didWarnOnInvalidCallback = new Set(); warnOnInvalidCallback = function(callback, callerName) { if (callback === null || typeof callback === "function") { return; } var key = callerName + "_" + callback; - if (!didWarnOnInvalidCallback[key]) { + if (!didWarnOnInvalidCallback.has(key)) { + didWarnOnInvalidCallback.add(key); warning( false, "%s(...): Expected the last optional `callback` argument to be a " + @@ -6066,7 +6150,6 @@ var warnOnInvalidCallback = void 0; callerName, callback ); - didWarnOnInvalidCallback[key] = true; } }; @@ -6209,12 +6292,14 @@ var ReactFiberClassComponent = function( stopPhaseTimer(); { - warning( - shouldUpdate !== undefined, - "%s.shouldComponentUpdate(): Returned undefined instead of a " + - "boolean value. Make sure to return true or false.", - getComponentName(workInProgress) || "Unknown" - ); + !(shouldUpdate !== undefined) + ? warning( + false, + "%s.shouldComponentUpdate(): Returned undefined instead of a " + + "boolean value. Make sure to return true or false.", + getComponentName(workInProgress) || "Component" + ) + : void 0; } return shouldUpdate; @@ -6233,7 +6318,7 @@ var ReactFiberClassComponent = function( var instance = workInProgress.stateNode; var type = workInProgress.type; { - var name = getComponentName(workInProgress); + var name = getComponentName(workInProgress) || "Component"; var renderPresent = instance.render; if (!renderPresent) { @@ -6258,47 +6343,57 @@ var ReactFiberClassComponent = function( !instance.getInitialState || instance.getInitialState.isReactClassApproved || instance.state; - warning( - noGetInitialStateOnES6, - "getInitialState was defined on %s, a plain JavaScript class. " + - "This is only supported for classes created using React.createClass. " + - "Did you mean to define a state property instead?", - name - ); + !noGetInitialStateOnES6 + ? warning( + false, + "getInitialState was defined on %s, a plain JavaScript class. " + + "This is only supported for classes created using React.createClass. " + + "Did you mean to define a state property instead?", + name + ) + : void 0; var noGetDefaultPropsOnES6 = !instance.getDefaultProps || instance.getDefaultProps.isReactClassApproved; - warning( - noGetDefaultPropsOnES6, - "getDefaultProps was defined on %s, a plain JavaScript class. " + - "This is only supported for classes created using React.createClass. " + - "Use a static property to define defaultProps instead.", - name - ); + !noGetDefaultPropsOnES6 + ? warning( + false, + "getDefaultProps was defined on %s, a plain JavaScript class. " + + "This is only supported for classes created using React.createClass. " + + "Use a static property to define defaultProps instead.", + name + ) + : void 0; var noInstancePropTypes = !instance.propTypes; - warning( - noInstancePropTypes, - "propTypes was defined as an instance property on %s. Use a static " + - "property to define propTypes instead.", - name - ); + !noInstancePropTypes + ? warning( + false, + "propTypes was defined as an instance property on %s. Use a static " + + "property to define propTypes instead.", + name + ) + : void 0; var noInstanceContextTypes = !instance.contextTypes; - warning( - noInstanceContextTypes, - "contextTypes was defined as an instance property on %s. Use a static " + - "property to define contextTypes instead.", - name - ); + !noInstanceContextTypes + ? warning( + false, + "contextTypes was defined as an instance property on %s. Use a static " + + "property to define contextTypes instead.", + name + ) + : void 0; var noComponentShouldUpdate = typeof instance.componentShouldUpdate !== "function"; - warning( - noComponentShouldUpdate, - "%s has a method called " + - "componentShouldUpdate(). Did you mean shouldComponentUpdate()? " + - "The name is phrased as a question because the function is " + - "expected to return a value.", - name - ); + !noComponentShouldUpdate + ? warning( + false, + "%s has a method called " + + "componentShouldUpdate(). Did you mean shouldComponentUpdate()? " + + "The name is phrased as a question because the function is " + + "expected to return a value.", + name + ) + : void 0; if ( type.prototype && type.prototype.isPureReactComponent && @@ -6314,73 +6409,128 @@ var ReactFiberClassComponent = function( } var noComponentDidUnmount = typeof instance.componentDidUnmount !== "function"; - warning( - noComponentDidUnmount, - "%s has a method called " + - "componentDidUnmount(). But there is no such lifecycle method. " + - "Did you mean componentWillUnmount()?", - name - ); + !noComponentDidUnmount + ? warning( + false, + "%s has a method called " + + "componentDidUnmount(). But there is no such lifecycle method. " + + "Did you mean componentWillUnmount()?", + name + ) + : void 0; var noComponentDidReceiveProps = typeof instance.componentDidReceiveProps !== "function"; - warning( - noComponentDidReceiveProps, - "%s has a method called " + - "componentDidReceiveProps(). But there is no such lifecycle method. " + - "If you meant to update the state in response to changing props, " + - "use componentWillReceiveProps(). If you meant to fetch data or " + - "run side-effects or mutations after React has updated the UI, use componentDidUpdate().", - name - ); + !noComponentDidReceiveProps + ? warning( + false, + "%s has a method called " + + "componentDidReceiveProps(). But there is no such lifecycle method. " + + "If you meant to update the state in response to changing props, " + + "use componentWillReceiveProps(). If you meant to fetch data or " + + "run side-effects or mutations after React has updated the UI, use componentDidUpdate().", + name + ) + : void 0; var noComponentWillRecieveProps = typeof instance.componentWillRecieveProps !== "function"; - warning( - noComponentWillRecieveProps, - "%s has a method called " + - "componentWillRecieveProps(). Did you mean componentWillReceiveProps()?", - name - ); + !noComponentWillRecieveProps + ? warning( + false, + "%s has a method called " + + "componentWillRecieveProps(). Did you mean componentWillReceiveProps()?", + name + ) + : void 0; var noUnsafeComponentWillRecieveProps = typeof instance.UNSAFE_componentWillRecieveProps !== "function"; - warning( - noUnsafeComponentWillRecieveProps, - "%s has a method called " + - "UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?", - name - ); + !noUnsafeComponentWillRecieveProps + ? warning( + false, + "%s has a method called " + + "UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?", + name + ) + : void 0; var hasMutatedProps = instance.props !== workInProgress.pendingProps; - warning( - instance.props === undefined || !hasMutatedProps, - "%s(...): When calling super() in `%s`, make sure to pass " + - "up the same props that your component's constructor was passed.", - name, - name - ); + !(instance.props === undefined || !hasMutatedProps) + ? warning( + false, + "%s(...): When calling super() in `%s`, make sure to pass " + + "up the same props that your component's constructor was passed.", + name, + name + ) + : void 0; var noInstanceDefaultProps = !instance.defaultProps; - warning( - noInstanceDefaultProps, - "Setting defaultProps as an instance property on %s is not supported and will be ignored." + - " Instead, define defaultProps as a static property on %s.", - name, - name - ); - } + !noInstanceDefaultProps + ? warning( + false, + "Setting defaultProps as an instance property on %s is not supported and will be ignored." + + " Instead, define defaultProps as a static property on %s.", + name, + name + ) + : void 0; - var state = instance.state; - if (state && (typeof state !== "object" || isArray(state))) { - warning( - false, - "%s.state: must be set to an object or null", - getComponentName(workInProgress) - ); - } - if (typeof instance.getChildContext === "function") { - warning( - typeof type.childContextTypes === "object", - "%s.getChildContext(): childContextTypes must be defined in order to " + - "use getChildContext().", - getComponentName(workInProgress) - ); + if ( + typeof instance.getSnapshotBeforeUpdate === "function" && + typeof instance.componentDidUpdate !== "function" && + typeof instance.componentDidUpdate !== "function" && + !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(type) + ) { + didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(type); + warning( + false, + "%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). " + + "This component defines getSnapshotBeforeUpdate() only.", + getComponentName(workInProgress) + ); + } + + var noInstanceGetDerivedStateFromProps = + typeof instance.getDerivedStateFromProps !== "function"; + !noInstanceGetDerivedStateFromProps + ? warning( + false, + "%s: getDerivedStateFromProps() is defined as an instance method " + + "and will be ignored. Instead, declare it as a static method.", + name + ) + : void 0; + var noInstanceGetDerivedStateFromCatch = + typeof instance.getDerivedStateFromCatch !== "function"; + !noInstanceGetDerivedStateFromCatch + ? warning( + false, + "%s: getDerivedStateFromCatch() is defined as an instance method " + + "and will be ignored. Instead, declare it as a static method.", + name + ) + : void 0; + var noStaticGetSnapshotBeforeUpdate = + typeof type.getSnapshotBeforeUpdate !== "function"; + !noStaticGetSnapshotBeforeUpdate + ? warning( + false, + "%s: getSnapshotBeforeUpdate() is defined as a static method " + + "and will be ignored. Instead, declare it as an instance method.", + name + ) + : void 0; + var _state = instance.state; + if (_state && (typeof _state !== "object" || isArray(_state))) { + warning(false, "%s.state: must be set to an object or null", name); + } + if (typeof instance.getChildContext === "function") { + !(typeof type.childContextTypes === "object") + ? warning( + false, + "%s.getChildContext(): childContextTypes must be defined in order to " + + "use getChildContext().", + name + ) + : void 0; + } } } @@ -6428,8 +6578,9 @@ var ReactFiberClassComponent = function( typeof ctor.getDerivedStateFromProps === "function" && state === null ) { - var componentName = getComponentName(workInProgress) || "Unknown"; - if (!didWarnAboutUninitializedState[componentName]) { + var componentName = getComponentName(workInProgress) || "Component"; + if (!didWarnAboutUninitializedState.has(componentName)) { + didWarnAboutUninitializedState.add(componentName); warning( false, "%s: Did not properly initialize state during construction. " + @@ -6437,7 +6588,75 @@ var ReactFiberClassComponent = function( componentName, instance.state === null ? "null" : "undefined" ); - didWarnAboutUninitializedState[componentName] = true; + } + } + + // If new component APIs are defined, "unsafe" lifecycles won't be called. + // Warn about these lifecycles if they are present. + // Don't warn about react-lifecycles-compat polyfilled methods though. + if ( + typeof ctor.getDerivedStateFromProps === "function" || + typeof instance.getSnapshotBeforeUpdate === "function" + ) { + var foundWillMountName = null; + var foundWillReceivePropsName = null; + var foundWillUpdateName = null; + if ( + typeof instance.componentWillMount === "function" && + instance.componentWillMount.__suppressDeprecationWarning !== true + ) { + foundWillMountName = "componentWillMount"; + } else if (typeof instance.UNSAFE_componentWillMount === "function") { + foundWillMountName = "UNSAFE_componentWillMount"; + } + if ( + typeof instance.componentWillReceiveProps === "function" && + instance.componentWillReceiveProps.__suppressDeprecationWarning !== + true + ) { + foundWillReceivePropsName = "componentWillReceiveProps"; + } else if ( + typeof instance.UNSAFE_componentWillReceiveProps === "function" + ) { + foundWillReceivePropsName = "UNSAFE_componentWillReceiveProps"; + } + if ( + typeof instance.componentWillUpdate === "function" && + instance.componentWillUpdate.__suppressDeprecationWarning !== true + ) { + foundWillUpdateName = "componentWillUpdate"; + } else if (typeof instance.UNSAFE_componentWillUpdate === "function") { + foundWillUpdateName = "UNSAFE_componentWillUpdate"; + } + if ( + foundWillMountName !== null || + foundWillReceivePropsName !== null || + foundWillUpdateName !== null + ) { + var _componentName = getComponentName(workInProgress) || "Component"; + var newApiName = + typeof ctor.getDerivedStateFromProps === "function" + ? "getDerivedStateFromProps()" + : "getSnapshotBeforeUpdate()"; + if ( + !didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName) + ) { + didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName); + warning( + false, + "Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n" + + "%s uses %s but also contains the following legacy lifecycles:%s%s%s\n\n" + + "The above lifecycles should be removed. Learn more about this warning here:\n" + + "https://fb.me/react-async-component-lifecycle-hooks", + _componentName, + newApiName, + foundWillMountName !== null ? "\n " + foundWillMountName : "", + foundWillReceivePropsName !== null + ? "\n " + foundWillReceivePropsName + : "", + foundWillUpdateName !== null ? "\n " + foundWillUpdateName : "" + ); + } } } } @@ -6447,7 +6666,8 @@ var ReactFiberClassComponent = function( var partialState = callGetDerivedStateFromProps( workInProgress, instance, - props + props, + state ); if (partialState !== null && partialState !== undefined) { @@ -6490,7 +6710,7 @@ var ReactFiberClassComponent = function( "%s.componentWillMount(): Assigning directly to this.state is " + "deprecated (except inside a component's " + "constructor). Use setState instead.", - getComponentName(workInProgress) + getComponentName(workInProgress) || "Component" ); } updater.enqueueReplaceState(instance, instance.state, null); @@ -6516,7 +6736,8 @@ var ReactFiberClassComponent = function( if (instance.state !== oldState) { { var componentName = getComponentName(workInProgress) || "Component"; - if (!didWarnAboutStateAssignmentForComponent[componentName]) { + if (!didWarnAboutStateAssignmentForComponent.has(componentName)) { + didWarnAboutStateAssignmentForComponent.add(componentName); warning( false, "%s.componentWillReceiveProps(): Assigning directly to " + @@ -6524,69 +6745,47 @@ var ReactFiberClassComponent = function( "constructor). Use setState instead.", componentName ); - didWarnAboutStateAssignmentForComponent[componentName] = true; } } updater.enqueueReplaceState(instance, instance.state, null); } } - function callGetDerivedStateFromProps(workInProgress, instance, props) { + function callGetDerivedStateFromProps( + workInProgress, + instance, + nextProps, + prevState + ) { var type = workInProgress.type; if (typeof type.getDerivedStateFromProps === "function") { - { - // Don't warn about react-lifecycles-compat polyfilled components - if ( - (typeof instance.componentWillReceiveProps === "function" && - instance.componentWillReceiveProps.__suppressDeprecationWarning !== - true) || - typeof instance.UNSAFE_componentWillReceiveProps === "function" - ) { - var componentName = getComponentName(workInProgress) || "Unknown"; - if (!didWarnAboutWillReceivePropsAndDerivedState[componentName]) { - warning( - false, - "%s: Defines both componentWillReceiveProps() and static " + - "getDerivedStateFromProps() methods. We recommend using " + - "only getDerivedStateFromProps().", - componentName - ); - didWarnAboutWillReceivePropsAndDerivedState[componentName] = true; - } - } - } - if ( debugRenderPhaseSideEffects || (debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) ) { // Invoke method an extra time to help detect side-effects. - type.getDerivedStateFromProps.call( - null, - props, - workInProgress.memoizedState - ); + type.getDerivedStateFromProps.call(null, nextProps, prevState); } var partialState = type.getDerivedStateFromProps.call( null, - props, - workInProgress.memoizedState + nextProps, + prevState ); { if (partialState === undefined) { - var _componentName = getComponentName(workInProgress) || "Unknown"; - if (!didWarnAboutUndefinedDerivedState[_componentName]) { + 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 + componentName ); - didWarnAboutUndefinedDerivedState[_componentName] = _componentName; } } } @@ -6630,11 +6829,12 @@ var ReactFiberClassComponent = function( } // In order to support react-lifecycles-compat polyfilled components, - // Unsafe lifecycles should not be invoked for any component with the new gDSFP. + // Unsafe lifecycles should not be invoked for components using the new APIs. if ( + typeof ctor.getDerivedStateFromProps !== "function" && + typeof instance.getSnapshotBeforeUpdate !== "function" && (typeof instance.UNSAFE_componentWillMount === "function" || - typeof instance.componentWillMount === "function") && - typeof ctor.getDerivedStateFromProps !== "function" + typeof instance.componentWillMount === "function") ) { callComponentWillMount(workInProgress, instance); // If we had additional state updates during this life-cycle, let's @@ -6667,16 +6867,20 @@ var ReactFiberClassComponent = function( var newUnmaskedContext = getUnmaskedContext(workInProgress); var newContext = getMaskedContext(workInProgress, newUnmaskedContext); + var hasNewLifecycles = + typeof ctor.getDerivedStateFromProps === "function" || + typeof instance.getSnapshotBeforeUpdate === "function"; + // Note: During these life-cycles, instance.props/instance.state are what // ever the previously attempted to render - not the "current". However, // during componentDidUpdate we pass the "current" props. // In order to support react-lifecycles-compat polyfilled components, - // Unsafe lifecycles should not be invoked for any component with the new gDSFP. + // Unsafe lifecycles should not be invoked for components using the new APIs. if ( + !hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === "function" || - typeof instance.componentWillReceiveProps === "function") && - typeof ctor.getDerivedStateFromProps !== "function" + typeof instance.componentWillReceiveProps === "function") ) { if (oldProps !== newProps || oldContext !== newContext) { callComponentWillReceiveProps( @@ -6688,15 +6892,6 @@ var ReactFiberClassComponent = function( } } - var derivedStateFromProps = void 0; - if (oldProps !== newProps) { - derivedStateFromProps = callGetDerivedStateFromProps( - workInProgress, - instance, - newProps - ); - } - // Compute the next state using the memoized state and the update queue. var oldState = workInProgress.memoizedState; // TODO: Previous state can be null. @@ -6733,6 +6928,18 @@ var ReactFiberClassComponent = function( newState = oldState; } + 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, + instance, + newProps, + newState + ); + } + 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. @@ -6741,6 +6948,17 @@ var ReactFiberClassComponent = function( 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, @@ -6750,6 +6968,17 @@ var ReactFiberClassComponent = function( 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 ( @@ -6780,11 +7009,11 @@ var ReactFiberClassComponent = function( if (shouldUpdate) { // In order to support react-lifecycles-compat polyfilled components, - // Unsafe lifecycles should not be invoked for any component with the new gDSFP. + // Unsafe lifecycles should not be invoked for components using the new APIs. if ( + !hasNewLifecycles && (typeof instance.UNSAFE_componentWillMount === "function" || - typeof instance.componentWillMount === "function") && - typeof ctor.getDerivedStateFromProps !== "function" + typeof instance.componentWillMount === "function") ) { startPhaseTimer(workInProgress, "componentWillMount"); if (typeof instance.componentWillMount === "function") { @@ -6832,16 +7061,20 @@ var ReactFiberClassComponent = function( var newUnmaskedContext = getUnmaskedContext(workInProgress); var newContext = getMaskedContext(workInProgress, newUnmaskedContext); + var hasNewLifecycles = + typeof ctor.getDerivedStateFromProps === "function" || + typeof instance.getSnapshotBeforeUpdate === "function"; + // Note: During these life-cycles, instance.props/instance.state are what // ever the previously attempted to render - not the "current". However, // during componentDidUpdate we pass the "current" props. // In order to support react-lifecycles-compat polyfilled components, - // Unsafe lifecycles should not be invoked for any component with the new gDSFP. + // Unsafe lifecycles should not be invoked for components using the new APIs. if ( + !hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === "function" || - typeof instance.componentWillReceiveProps === "function") && - typeof ctor.getDerivedStateFromProps !== "function" + typeof instance.componentWillReceiveProps === "function") ) { if (oldProps !== newProps || oldContext !== newContext) { callComponentWillReceiveProps( @@ -6853,20 +7086,12 @@ var ReactFiberClassComponent = function( } } - var derivedStateFromProps = void 0; - if (oldProps !== newProps) { - derivedStateFromProps = callGetDerivedStateFromProps( - workInProgress, - instance, - newProps - ); - } - // Compute the next state using the memoized state and the update queue. var oldState = workInProgress.memoizedState; // TODO: Previous state can be null. var newState = void 0; var derivedStateFromCatch = void 0; + if (workInProgress.updateQueue !== null) { newState = processUpdateQueue( current, @@ -6898,6 +7123,18 @@ var ReactFiberClassComponent = function( newState = oldState; } + 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, + instance, + newProps, + newState + ); + } + 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. @@ -6906,6 +7143,17 @@ var ReactFiberClassComponent = function( 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, @@ -6915,6 +7163,17 @@ var ReactFiberClassComponent = function( 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 ( @@ -6936,6 +7195,14 @@ var ReactFiberClassComponent = function( workInProgress.effectTag |= Update; } } + if (typeof instance.getSnapshotBeforeUpdate === "function") { + if ( + oldProps !== current.memoizedProps || + oldState !== current.memoizedState + ) { + workInProgress.effectTag |= Snapshot; + } + } return false; } @@ -6950,11 +7217,11 @@ var ReactFiberClassComponent = function( if (shouldUpdate) { // In order to support react-lifecycles-compat polyfilled components, - // Unsafe lifecycles should not be invoked for any component with the new gDSFP. + // Unsafe lifecycles should not be invoked for components using the new APIs. if ( + !hasNewLifecycles && (typeof instance.UNSAFE_componentWillUpdate === "function" || - typeof instance.componentWillUpdate === "function") && - typeof ctor.getDerivedStateFromProps !== "function" + typeof instance.componentWillUpdate === "function") ) { startPhaseTimer(workInProgress, "componentWillUpdate"); if (typeof instance.componentWillUpdate === "function") { @@ -6968,6 +7235,9 @@ var ReactFiberClassComponent = function( if (typeof instance.componentDidUpdate === "function") { workInProgress.effectTag |= Update; } + if (typeof instance.getSnapshotBeforeUpdate === "function") { + workInProgress.effectTag |= Snapshot; + } } else { // If an update was already in progress, we should schedule an Update // effect even though we're bailing out, so that cWU/cDU are called. @@ -6979,6 +7249,14 @@ var ReactFiberClassComponent = function( workInProgress.effectTag |= Update; } } + if (typeof instance.getSnapshotBeforeUpdate === "function") { + if ( + oldProps !== current.memoizedProps || + oldState !== current.memoizedState + ) { + workInProgress.effectTag |= Snapshot; + } + } // If shouldComponentUpdate returned false, we should still update the // memoized props/state to indicate that this work can be reused. @@ -7818,13 +8096,15 @@ function ChildReconciler(shouldTrackSideEffects) { if (typeof newChildrenIterable.entries === "function") { var possibleMap = newChildrenIterable; if (possibleMap.entries === iteratorFn) { - warning( - didWarnAboutMaps, - "Using Maps as children is unsupported and will likely yield " + - "unexpected results. Convert it to a sequence/iterable of keyed " + - "ReactElements instead.%s", - getCurrentFiberStackAddendum$1() - ); + !didWarnAboutMaps + ? warning( + false, + "Using Maps as children is unsupported and will likely yield " + + "unexpected results. Convert it to a sequence/iterable of keyed " + + "ReactElements instead.%s", + getCurrentFiberStackAddendum$1() + ) + : void 0; didWarnAboutMaps = true; } } @@ -8790,7 +9070,8 @@ var ReactFiberBeginWork = function( var partialState = callGetDerivedStateFromProps( workInProgress, value, - props + props, + workInProgress.memoizedState ); if (partialState !== null && partialState !== undefined) { @@ -8823,11 +9104,13 @@ var ReactFiberBeginWork = function( var _Component = workInProgress.type; if (_Component) { - warning( - !_Component.childContextTypes, - "%s(...): childContextTypes cannot be defined on a functional component.", - _Component.displayName || _Component.name || "Component" - ); + !!_Component.childContextTypes + ? warning( + false, + "%s(...): childContextTypes cannot be defined on a functional component.", + _Component.displayName || _Component.name || "Component" + ) + : void 0; } if (workInProgress.ref !== null) { var info = ""; @@ -9046,7 +9329,7 @@ var ReactFiberBeginWork = function( renderExpirationTime ) { var providerType = workInProgress.type; - var context = providerType.context; + var context = providerType._context; var newProps = workInProgress.pendingProps; var oldProps = workInProgress.memoizedProps; @@ -9099,12 +9382,14 @@ var ReactFiberBeginWork = function( ? context._calculateChangedBits(oldValue, newValue) : MAX_SIGNED_31_BIT_INT; { - warning( - (changedBits & MAX_SIGNED_31_BIT_INT) === changedBits, - "calculateChangedBits: Expected the return value to be a " + - "31-bit integer. Instead received: %s", - changedBits - ); + !((changedBits & MAX_SIGNED_31_BIT_INT) === changedBits) + ? warning( + false, + "calculateChangedBits: Expected the return value to be a " + + "31-bit integer. Instead received: %s", + changedBits + ) + : void 0; } changedBits |= 0; @@ -9172,21 +9457,23 @@ var ReactFiberBeginWork = function( changedBits, renderExpirationTime ); - } else if (oldProps !== null && oldProps.children === newProps.children) { - // No change. Bailout early if children are the same. - return bailoutOnAlreadyFinishedWork(current, workInProgress); } + // There is no bailout on `children` equality because we expect people + // to often pass a bound method as a child, but it may reference + // `this.state` or `this.props` (and thus needs to re-render on `setState`). var render = newProps.children; { - warning( - typeof render === "function", - "A context consumer was rendered with multiple children, or a child " + - "that isn't a function. A context consumer expects a single child " + - "that is a function. If you did pass a function, make sure there " + - "is no trailing or leading whitespace around it." - ); + !(typeof render === "function") + ? warning( + false, + "A context consumer was rendered with multiple children, or a child " + + "that isn't a function. A context consumer expects a single child " + + "that is a function. If you did pass a function, make sure there " + + "is no trailing or leading whitespace around it." + ) + : void 0; } var newChildren = render(newValue); @@ -10175,6 +10462,11 @@ var invokeGuardedCallback$3 = ReactErrorUtils.invokeGuardedCallback; var hasCaughtError$1 = ReactErrorUtils.hasCaughtError; var clearCaughtError$1 = ReactErrorUtils.clearCaughtError; +var didWarnAboutUndefinedSnapshotBeforeUpdate = null; +{ + didWarnAboutUndefinedSnapshotBeforeUpdate = new Set(); +} + function logError(boundary, errorInfo) { var source = errorInfo.source; var stack = errorInfo.stack; @@ -10184,21 +10476,19 @@ function logError(boundary, errorInfo) { var capturedError = { componentName: source !== null ? getComponentName(source) : null, - error: errorInfo.value, - errorBoundary: boundary, componentStack: stack !== null ? stack : "", + error: errorInfo.value, + errorBoundary: null, errorBoundaryName: null, errorBoundaryFound: false, willRetry: false }; - if (boundary !== null) { + if (boundary !== null && boundary.tag === ClassComponent) { + capturedError.errorBoundary = boundary.stateNode; capturedError.errorBoundaryName = getComponentName(boundary); - capturedError.errorBoundaryFound = capturedError.willRetry = - boundary.tag === ClassComponent; - } else { - capturedError.errorBoundaryName = null; - capturedError.errorBoundaryFound = capturedError.willRetry = false; + capturedError.errorBoundaryFound = true; + capturedError.willRetry = true; } try { @@ -10267,6 +10557,58 @@ var ReactFiberCommitWork = function( } } + function commitBeforeMutationLifeCycles(current, finishedWork) { + switch (finishedWork.tag) { + case ClassComponent: { + if (finishedWork.effectTag & Snapshot) { + if (current !== null) { + var prevProps = current.memoizedProps; + var prevState = current.memoizedState; + startPhaseTimer(finishedWork, "getSnapshotBeforeUpdate"); + var _instance = finishedWork.stateNode; + _instance.props = finishedWork.memoizedProps; + _instance.state = finishedWork.memoizedState; + var snapshot = _instance.getSnapshotBeforeUpdate( + prevProps, + prevState + ); + { + var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate; + if ( + snapshot === undefined && + !didWarnSet.has(finishedWork.type) + ) { + didWarnSet.add(finishedWork.type); + warning( + false, + "%s.getSnapshotBeforeUpdate(): A snapshot value (or null) " + + "must be returned. You have returned undefined.", + getComponentName(finishedWork) + ); + } + } + _instance.__reactInternalSnapshotBeforeUpdate = snapshot; + stopPhaseTimer(); + } + } + return; + } + case HostRoot: + case HostComponent: + case HostText: + case HostPortal: + // Nothing to do for these component types + return; + default: { + invariant( + false, + "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, @@ -10276,50 +10618,54 @@ var ReactFiberCommitWork = function( ) { switch (finishedWork.tag) { case ClassComponent: { - var _instance = finishedWork.stateNode; + var _instance2 = finishedWork.stateNode; if (finishedWork.effectTag & Update) { if (current === null) { startPhaseTimer(finishedWork, "componentDidMount"); - _instance.props = finishedWork.memoizedProps; - _instance.state = finishedWork.memoizedState; - _instance.componentDidMount(); + _instance2.props = finishedWork.memoizedProps; + _instance2.state = finishedWork.memoizedState; + _instance2.componentDidMount(); stopPhaseTimer(); } else { var prevProps = current.memoizedProps; var prevState = current.memoizedState; startPhaseTimer(finishedWork, "componentDidUpdate"); - _instance.props = finishedWork.memoizedProps; - _instance.state = finishedWork.memoizedState; - _instance.componentDidUpdate(prevProps, prevState); + _instance2.props = finishedWork.memoizedProps; + _instance2.state = finishedWork.memoizedState; + _instance2.componentDidUpdate( + prevProps, + prevState, + _instance2.__reactInternalSnapshotBeforeUpdate + ); stopPhaseTimer(); } } var updateQueue = finishedWork.updateQueue; if (updateQueue !== null) { - commitCallbacks(updateQueue, _instance); + commitCallbacks(updateQueue, _instance2); } return; } case HostRoot: { var _updateQueue = finishedWork.updateQueue; if (_updateQueue !== null) { - var _instance2 = null; + var _instance3 = null; if (finishedWork.child !== null) { switch (finishedWork.child.tag) { case HostComponent: - _instance2 = getPublicInstance(finishedWork.child.stateNode); + _instance3 = getPublicInstance(finishedWork.child.stateNode); break; case ClassComponent: - _instance2 = finishedWork.child.stateNode; + _instance3 = finishedWork.child.stateNode; break; } } - commitCallbacks(_updateQueue, _instance2); + commitCallbacks(_updateQueue, _instance3); } return; } case HostComponent: { - var _instance3 = finishedWork.stateNode; + var _instance4 = finishedWork.stateNode; // Renderers may schedule work to be done after host components are mounted // (eg DOM renderer may schedule auto-focus for inputs and form controls). @@ -10328,7 +10674,7 @@ var ReactFiberCommitWork = function( if (current === null && finishedWork.effectTag & Update) { var type = finishedWork.type; var props = finishedWork.memoizedProps; - commitMount(_instance3, type, props, finishedWork); + commitMount(_instance4, type, props, finishedWork); } return; @@ -10356,7 +10702,7 @@ var ReactFiberCommitWork = function( case ClassComponent: { var ctor = finishedWork.type; - var _instance4 = finishedWork.stateNode; + var _instance5 = finishedWork.stateNode; var updateQueue = finishedWork.updateQueue; invariant( updateQueue !== null && updateQueue.capturedValues !== null, @@ -10373,16 +10719,19 @@ var ReactFiberCommitWork = function( // This gets reset before we yield back to the browser. // TODO: Warn in strict mode if getDerivedStateFromCatch is // not defined. - markLegacyErrorBoundaryAsFailed(_instance4); + markLegacyErrorBoundaryAsFailed(_instance5); } - _instance4.props = finishedWork.memoizedProps; - _instance4.state = finishedWork.memoizedState; + _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); - _instance4.componentDidCatch(_error); + _instance5.componentDidCatch(_error, { + componentStack: stack !== null ? stack : "" + }); } } break; @@ -10415,14 +10764,14 @@ var ReactFiberCommitWork = function( 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); @@ -10466,9 +10815,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; } @@ -10605,6 +10954,7 @@ var ReactFiberCommitWork = function( }, commitLifeCycles: commitLifeCycles, + commitBeforeMutationLifeCycles: commitBeforeMutationLifeCycles, commitErrorLogging: commitErrorLogging, commitAttachRef: commitAttachRef, commitDetachRef: commitDetachRef @@ -10863,8 +11213,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 @@ -10877,7 +11227,7 @@ var ReactFiberCommitWork = function( finishedWork.updateQueue = null; if (updatePayload !== null) { commitUpdate( - _instance7, + _instance8, updatePayload, type, oldProps, @@ -10922,6 +11272,7 @@ var ReactFiberCommitWork = function( if (enableMutatingReconciler) { return { + commitBeforeMutationLifeCycles: commitBeforeMutationLifeCycles, commitResetTextContent: commitResetTextContent, commitPlacement: commitPlacement, commitDeletion: commitDeletion, @@ -10967,12 +11318,19 @@ var ReactFiberHostContext = function(config, stack) { // Push current root instance onto the stack; // This allows us to reset root when portals are popped. push(rootInstanceStackCursor, nextRootInstance, fiber); - - var nextRootContext = getRootHostContext(nextRootInstance); - // Track the context and the Fiber that provided it. // This enables us to pop only Fibers that provide unique contexts. push(contextFiberStackCursor, fiber, fiber); + + // Finally, we need to push the host context to the stack. + // However, we can't just call getRootHostContext() and push it because + // we'd have a different number of entries on the stack depending on + // whether getRootHostContext() throws somewhere in renderer code or not. + // So we push an empty value first. This lets us safely unwind on errors. + push(contextStackCursor, NO_CONTEXT, fiber); + var nextRootContext = getRootHostContext(nextRootInstance); + // Now that we know this function doesn't throw, replace it. + pop(contextStackCursor, fiber); push(contextStackCursor, nextRootContext, fiber); } @@ -11683,7 +12041,7 @@ var ReactFiberNewContext = function(stack) { } function pushProvider(providerFiber) { - var context = providerFiber.type.context; + var context = providerFiber.type._context; push(changedBitsCursor, context._changedBits, providerFiber); push(valueCursor, context._currentValue, providerFiber); @@ -11693,12 +12051,16 @@ var ReactFiberNewContext = function(stack) { context._changedBits = providerFiber.stateNode; { - warning( + !( context._currentRenderer === null || - context._currentRenderer === rendererSigil, - "Detected multiple renderers concurrently rendering the " + - "same context provider. This is currently unsupported." - ); + context._currentRenderer === rendererSigil + ) + ? warning( + false, + "Detected multiple renderers concurrently rendering the " + + "same context provider. This is currently unsupported." + ) + : void 0; context._currentRenderer = rendererSigil; } } @@ -11711,7 +12073,7 @@ var ReactFiberNewContext = function(stack) { pop(valueCursor, providerFiber); pop(changedBitsCursor, providerFiber); - var context = providerFiber.type.context; + var context = providerFiber.type._context; context._currentValue = currentValue; context._changedBits = changedBits; } @@ -11824,17 +12186,19 @@ var warnAboutInvalidUpdates = void 0; var didWarnStateUpdateForUnmountedComponent = {}; warnAboutUpdateOnUnmounted = function(fiber) { + // We show the whole stack but dedupe on the top component's name because + // the problematic code almost always lies inside that component. var componentName = getComponentName(fiber) || "ReactClass"; if (didWarnStateUpdateForUnmountedComponent[componentName]) { return; } warning( false, - "Can only update a mounted or mounting " + - "component. This usually means you called setState, replaceState, " + - "or forceUpdate on an unmounted component. This is a no-op.\n\nPlease " + - "check the code for the %s component.", - componentName + "Can't call setState (or forceUpdate) on an unmounted component. This " + + "is a no-op, but it indicates a memory leak in your application. To " + + "fix, cancel all subscriptions and asynchronous tasks in the " + + "componentWillUnmount method.%s", + getStackAddendumByWorkInProgressFiber(fiber) ); didWarnStateUpdateForUnmountedComponent[componentName] = true; }; @@ -11920,6 +12284,8 @@ var ReactFiberScheduler = function(config) { markLegacyErrorBoundaryAsFailed, recalculateCurrentTime ), + commitBeforeMutationLifeCycles = + _ReactFiberCommitWork.commitBeforeMutationLifeCycles, commitResetTextContent = _ReactFiberCommitWork.commitResetTextContent, commitPlacement = _ReactFiberCommitWork.commitPlacement, commitDeletion = _ReactFiberCommitWork.commitDeletion, @@ -11971,11 +12337,19 @@ var ReactFiberScheduler = function(config) { var stashedWorkInProgressProperties = void 0; var replayUnitOfWork = void 0; + var isReplayingFailedUnitOfWork = void 0; + var originalReplayError = void 0; + var rethrowOriginalError = void 0; if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) { stashedWorkInProgressProperties = null; - replayUnitOfWork = function(failedUnitOfWork, isAsync) { - // Retore the original state of the work-in-progress - Object.assign(failedUnitOfWork, stashedWorkInProgressProperties); + isReplayingFailedUnitOfWork = false; + originalReplayError = null; + replayUnitOfWork = function(failedUnitOfWork, error, isAsync) { + // Restore the original state of the work-in-progress + assignFiberPropertiesInDEV( + failedUnitOfWork, + stashedWorkInProgressProperties + ); switch (failedUnitOfWork.tag) { case HostRoot: popHostContainer(failedUnitOfWork); @@ -11995,14 +12369,22 @@ var ReactFiberScheduler = function(config) { break; } // Replay the begin phase. + isReplayingFailedUnitOfWork = true; + originalReplayError = error; invokeGuardedCallback$2(null, workLoop, null, isAsync); + isReplayingFailedUnitOfWork = false; + originalReplayError = null; if (hasCaughtError()) { clearCaughtError(); } else { - // This should be unreachable because the render phase is - // idempotent + // If the begin phase did not fail the second time, set this pointer + // back to the original value. + nextUnitOfWork = failedUnitOfWork; } }; + rethrowOriginalError = function() { + throw originalReplayError; + }; } function resetStack() { @@ -12034,6 +12416,7 @@ var ReactFiberScheduler = function(config) { recordEffect(); var effectTag = nextEffect.effectTag; + if (effectTag & ContentReset) { commitResetTextContent(nextEffect); } @@ -12091,6 +12474,22 @@ var ReactFiberScheduler = function(config) { } } + function commitBeforeMutationLifecycles() { + while (nextEffect !== null) { + var effectTag = nextEffect.effectTag; + + if (effectTag & Snapshot) { + recordEffect(); + var current = nextEffect.alternate; + commitBeforeMutationLifeCycles(current, nextEffect); + } + + // Don't cleanup effects yet; + // This will be done by commitAllLifeCycles() + nextEffect = nextEffect.nextEffect; + } + } + function commitAllLifeCycles( finishedRoot, currentTime, @@ -12198,16 +12597,14 @@ var ReactFiberScheduler = function(config) { prepareForCommit(root.containerInfo); - // Commit all the side-effects within a tree. We'll do this in two passes. - // The first pass performs all the host insertions, updates, deletions and - // ref unmounts. + // Invoke instances of getSnapshotBeforeUpdate before mutation. nextEffect = firstEffect; - startCommitHostEffectsTimer(); + startCommitSnapshotEffectsTimer(); while (nextEffect !== null) { var didError = false; var error = void 0; { - invokeGuardedCallback$2(null, commitAllHostEffects, null); + invokeGuardedCallback$2(null, commitBeforeMutationLifecycles, null); if (hasCaughtError()) { didError = true; error = clearCaughtError(); @@ -12226,6 +12623,36 @@ var ReactFiberScheduler = function(config) { } } } + stopCommitSnapshotEffectsTimer(); + + // Commit all the side-effects within a tree. We'll do this in two passes. + // The first pass performs all the host insertions, updates, deletions and + // ref unmounts. + nextEffect = firstEffect; + startCommitHostEffectsTimer(); + while (nextEffect !== null) { + var _didError = false; + var _error = void 0; + { + invokeGuardedCallback$2(null, commitAllHostEffects, null); + if (hasCaughtError()) { + _didError = true; + _error = clearCaughtError(); + } + } + if (_didError) { + invariant( + nextEffect !== null, + "Should have next effect. This error is likely caused by a bug " + + "in React. Please file an issue." + ); + onCommitPhaseError(nextEffect, _error); + // Clean-up + if (nextEffect !== null) { + nextEffect = nextEffect.nextEffect; + } + } + } stopCommitHostEffectsTimer(); resetAfterCommit(root.containerInfo); @@ -12243,8 +12670,8 @@ var ReactFiberScheduler = function(config) { nextEffect = firstEffect; startCommitLifeCyclesTimer(); while (nextEffect !== null) { - var _didError = false; - var _error = void 0; + var _didError2 = false; + var _error2 = void 0; { invokeGuardedCallback$2( null, @@ -12255,17 +12682,17 @@ var ReactFiberScheduler = function(config) { committedExpirationTime ); if (hasCaughtError()) { - _didError = true; - _error = clearCaughtError(); + _didError2 = true; + _error2 = clearCaughtError(); } } - if (_didError) { + if (_didError2) { invariant( nextEffect !== null, "Should have next effect. This error is likely caused by a bug " + "in React. Please file an issue." ); - onCommitPhaseError(nextEffect, _error); + onCommitPhaseError(nextEffect, _error2); if (nextEffect !== null) { nextEffect = nextEffect.nextEffect; } @@ -12489,12 +12916,21 @@ var ReactFiberScheduler = function(config) { } if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) { - stashedWorkInProgressProperties = Object.assign({}, workInProgress); + stashedWorkInProgressProperties = assignFiberPropertiesInDEV( + stashedWorkInProgressProperties, + workInProgress + ); } var next = beginWork(current, workInProgress, nextRenderExpirationTime); - { ReactDebugCurrentFiber.resetCurrentFiber(); + if (isReplayingFailedUnitOfWork) { + // Currently replaying a failed unit of work. This should be unreachable, + // because the render phase is meant to be idempotent, and it should + // have thrown again. Since it didn't, rethrow the original error, so + // React's internal stack is not misaligned. + rethrowOriginalError(); + } } if (true && ReactFiberInstrumentation_1.debugTool) { ReactFiberInstrumentation_1.debugTool.onBeginWork(workInProgress); @@ -12568,13 +13004,18 @@ var ReactFiberScheduler = function(config) { if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) { var failedUnitOfWork = nextUnitOfWork; - replayUnitOfWork(failedUnitOfWork, isAsync); + replayUnitOfWork(failedUnitOfWork, thrownValue, isAsync); } var sourceFiber = nextUnitOfWork; var returnFiber = sourceFiber["return"]; if (returnFiber === null) { - // This is a fatal error. + // 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 + // context. This information is needed to avoid a stack mismatch. + // Because we're not sure, treat this as a fatal error. We could track + // which phase it fails in, but doesn't seem worth it. At least + // for now. didFatal = true; onUncaughtError(thrownValue); break; @@ -12586,12 +13027,13 @@ var ReactFiberScheduler = function(config) { } while (true); // We're done performing work. Time to clean up. - stopWorkLoopTimer(interruptedBy); - interruptedBy = null; + var didCompleteRoot = false; isWorking = false; // Yield back to main thread. if (didFatal) { + stopWorkLoopTimer(interruptedBy, didCompleteRoot); + interruptedBy = null; // There was a fatal error. { stack.resetStackAfterFatalErrorInDev(); @@ -12600,12 +13042,17 @@ var ReactFiberScheduler = function(config) { } else if (nextUnitOfWork === null) { // We reached the root. if (isRootReadyForCommit) { + didCompleteRoot = true; + stopWorkLoopTimer(interruptedBy, didCompleteRoot); + interruptedBy = null; // The root successfully completed. It's ready for commit. root.pendingCommitExpirationTime = expirationTime; var finishedWork = root.current.alternate; return finishedWork; } else { // The root did not complete. + stopWorkLoopTimer(interruptedBy, didCompleteRoot); + interruptedBy = null; invariant( false, "Expired work should have completed. This error is likely caused " + @@ -12613,6 +13060,8 @@ var ReactFiberScheduler = function(config) { ); } } else { + stopWorkLoopTimer(interruptedBy, didCompleteRoot); + interruptedBy = null; // There's more work to do, but we ran out of time. Yield back to // the renderer. return null; @@ -12798,7 +13247,15 @@ var ReactFiberScheduler = function(config) { interruptedBy = fiber; resetStack(); } - if (nextRoot !== root || !isWorking) { + if ( + // If we're in the render phase, we don't need to schedule this root + // for an update, because we'll do it before we exit... + !isWorking || + isCommitting || + // ...unless this is a different root than the one we're rendering. + nextRoot !== root + ) { + // Add this root to the root schedule. requestWork(root, expirationTime); } if (nestedUpdateCount > NESTED_UPDATE_LIMIT) { @@ -13058,7 +13515,8 @@ var ReactFiberScheduler = function(config) { if (enableUserTimingAPI && deadline !== null) { var didExpire = nextFlushedExpirationTime < recalculateCurrentTime(); - stopRequestCallbackTimer(didExpire); + var timeout = expirationTimeToMs(nextFlushedExpirationTime); + stopRequestCallbackTimer(didExpire, timeout); } if (isAsync) { @@ -13118,7 +13576,11 @@ var ReactFiberScheduler = function(config) { // Perform work on root as if the given expiration time is the current time. // This has the effect of synchronously flushing all work up to and // including the given time. + nextFlushedRoot = root; + nextFlushedExpirationTime = expirationTime; performWorkOnRoot(root, expirationTime, false); + // Flush any sync work that was scheduled by lifecycles + performSyncWork(); finishRendering(); } @@ -13445,12 +13907,14 @@ var ReactFiberReconciler$1 = function(config) { callback = callback === undefined ? null : callback; { - warning( - callback === null || typeof callback === "function", - "render(...): Expected the last optional `callback` argument to be a " + - "function. Instead received: %s.", - callback - ); + !(callback === null || typeof callback === "function") + ? warning( + false, + "render(...): Expected the last optional `callback` argument to be a " + + "function. Instead received: %s.", + callback + ) + : void 0; } var update = { @@ -13772,7 +14236,8 @@ var frameDeadline = 0; var frameDeadlineObject = { timeRemaining: function() { return frameDeadline - now(); - } + }, + didTimeout: false }; function setTimeoutCallback() { diff --git a/Libraries/Renderer/ReactNativeRenderer-prod.js b/Libraries/Renderer/ReactNativeRenderer-prod.js index f11aa6c82..055ddd7bb 100644 --- a/Libraries/Renderer/ReactNativeRenderer-prod.js +++ b/Libraries/Renderer/ReactNativeRenderer-prod.js @@ -2246,23 +2246,20 @@ function ReactFiberClassComponent( instance.state !== workInProgress && updater.enqueueReplaceState(instance, instance.state, null); } - function callGetDerivedStateFromProps(workInProgress, instance, props) { + function callGetDerivedStateFromProps( + workInProgress, + instance, + nextProps, + prevState + ) { instance = workInProgress.type; if ("function" === typeof instance.getDerivedStateFromProps) return ( (debugRenderPhaseSideEffects || (debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & 2)) && - instance.getDerivedStateFromProps.call( - null, - props, - workInProgress.memoizedState - ), - instance.getDerivedStateFromProps.call( - null, - props, - workInProgress.memoizedState - ) + instance.getDerivedStateFromProps.call(null, nextProps, prevState), + instance.getDerivedStateFromProps.call(null, nextProps, prevState) ); } var cacheContext = legacyContext.cacheContext, @@ -2337,7 +2334,7 @@ function ReactFiberClassComponent( null !== ctor.state && void 0 !== ctor.state ? ctor.state : null; adoptClassInstance(workInProgress, ctor); workInProgress.memoizedState = state; - props = callGetDerivedStateFromProps(workInProgress, ctor, props); + props = callGetDerivedStateFromProps(workInProgress, ctor, props, state); null !== props && void 0 !== props && (workInProgress.memoizedState = Object.assign( @@ -2358,9 +2355,10 @@ function ReactFiberClassComponent( instance.state = workInProgress.memoizedState; instance.refs = emptyObject; instance.context = getMaskedContext(workInProgress, unmaskedContext); - ("function" !== typeof instance.UNSAFE_componentWillMount && - "function" !== typeof instance.componentWillMount) || - "function" === typeof ctor.getDerivedStateFromProps || + "function" === typeof ctor.getDerivedStateFromProps || + "function" === typeof instance.getSnapshotBeforeUpdate || + ("function" !== typeof instance.UNSAFE_componentWillMount && + "function" !== typeof instance.componentWillMount) || ((ctor = instance.state), "function" === typeof instance.componentWillMount && instance.componentWillMount(), @@ -2391,9 +2389,12 @@ function ReactFiberClassComponent( oldContext = instance.context, newUnmaskedContext = getUnmaskedContext(workInProgress); newUnmaskedContext = getMaskedContext(workInProgress, newUnmaskedContext); - ("function" !== typeof instance.UNSAFE_componentWillReceiveProps && - "function" !== typeof instance.componentWillReceiveProps) || + var hasNewLifecycles = "function" === typeof ctor.getDerivedStateFromProps || + "function" === typeof instance.getSnapshotBeforeUpdate; + hasNewLifecycles || + ("function" !== typeof instance.UNSAFE_componentWillReceiveProps && + "function" !== typeof instance.componentWillReceiveProps) || ((oldProps !== newProps || oldContext !== newUnmaskedContext) && callComponentWillReceiveProps( workInProgress, @@ -2401,15 +2402,8 @@ function ReactFiberClassComponent( newProps, newUnmaskedContext )); - oldContext = void 0; - oldProps !== newProps && - (oldContext = callGetDerivedStateFromProps( - workInProgress, - instance, - newProps - )); - var oldState = workInProgress.memoizedState, - derivedStateFromCatch = void 0; + oldContext = workInProgress.memoizedState; + var derivedStateFromCatch = void 0; if (null !== workInProgress.updateQueue) { renderExpirationTime = processUpdateQueue( null, @@ -2428,23 +2422,45 @@ function ReactFiberClassComponent( ctor, updateQueue.capturedValues )); - } else renderExpirationTime = oldState; - null !== oldContext && - void 0 !== oldContext && - (renderExpirationTime = + } else renderExpirationTime = oldContext; + ctor = void 0; + oldProps !== newProps && + (ctor = callGetDerivedStateFromProps( + workInProgress, + instance, + newProps, + renderExpirationTime + )); + null !== ctor && + void 0 !== ctor && + ((renderExpirationTime = null === renderExpirationTime || void 0 === renderExpirationTime - ? oldContext - : Object.assign({}, renderExpirationTime, oldContext)); + ? ctor + : Object.assign({}, renderExpirationTime, ctor)), + (updateQueue = workInProgress.updateQueue), + null !== updateQueue && + (updateQueue.baseState = Object.assign( + {}, + updateQueue.baseState, + ctor + ))); null !== derivedStateFromCatch && void 0 !== derivedStateFromCatch && - (renderExpirationTime = + ((renderExpirationTime = null === renderExpirationTime || void 0 === renderExpirationTime ? derivedStateFromCatch - : Object.assign({}, renderExpirationTime, derivedStateFromCatch)); + : Object.assign({}, renderExpirationTime, derivedStateFromCatch)), + (ctor = workInProgress.updateQueue), + null !== ctor && + (ctor.baseState = Object.assign( + {}, + ctor.baseState, + derivedStateFromCatch + ))); if ( !( oldProps !== newProps || - oldState !== renderExpirationTime || + oldContext !== renderExpirationTime || hasContextChanged() || (null !== workInProgress.updateQueue && workInProgress.updateQueue.hasForceUpdate) @@ -2459,13 +2475,13 @@ function ReactFiberClassComponent( workInProgress, oldProps, newProps, - oldState, + oldContext, renderExpirationTime, newUnmaskedContext )) - ? (("function" !== typeof instance.UNSAFE_componentWillMount && - "function" !== typeof instance.componentWillMount) || - "function" === typeof ctor.getDerivedStateFromProps || + ? (hasNewLifecycles || + ("function" !== typeof instance.UNSAFE_componentWillMount && + "function" !== typeof instance.componentWillMount) || ("function" === typeof instance.componentWillMount && instance.componentWillMount(), "function" === typeof instance.UNSAFE_componentWillMount && @@ -2495,9 +2511,12 @@ function ReactFiberClassComponent( oldContext = instance.context, newUnmaskedContext = getUnmaskedContext(workInProgress); newUnmaskedContext = getMaskedContext(workInProgress, newUnmaskedContext); - ("function" !== typeof instance.UNSAFE_componentWillReceiveProps && - "function" !== typeof instance.componentWillReceiveProps) || + var hasNewLifecycles = "function" === typeof ctor.getDerivedStateFromProps || + "function" === typeof instance.getSnapshotBeforeUpdate; + hasNewLifecycles || + ("function" !== typeof instance.UNSAFE_componentWillReceiveProps && + "function" !== typeof instance.componentWillReceiveProps) || ((oldProps !== newProps || oldContext !== newUnmaskedContext) && callComponentWillReceiveProps( workInProgress, @@ -2505,13 +2524,6 @@ function ReactFiberClassComponent( newProps, newUnmaskedContext )); - var derivedStateFromProps = void 0; - oldProps !== newProps && - (derivedStateFromProps = callGetDerivedStateFromProps( - workInProgress, - instance, - newProps - )); oldContext = workInProgress.memoizedState; var derivedStateFromCatch = void 0; if (null !== workInProgress.updateQueue) { @@ -2533,18 +2545,40 @@ function ReactFiberClassComponent( updateQueue.capturedValues )); } else renderExpirationTime = oldContext; - null !== derivedStateFromProps && - void 0 !== derivedStateFromProps && - (renderExpirationTime = + ctor = void 0; + oldProps !== newProps && + (ctor = callGetDerivedStateFromProps( + workInProgress, + instance, + newProps, + renderExpirationTime + )); + null !== ctor && + void 0 !== ctor && + ((renderExpirationTime = null === renderExpirationTime || void 0 === renderExpirationTime - ? derivedStateFromProps - : Object.assign({}, renderExpirationTime, derivedStateFromProps)); + ? ctor + : Object.assign({}, renderExpirationTime, ctor)), + (updateQueue = workInProgress.updateQueue), + null !== updateQueue && + (updateQueue.baseState = Object.assign( + {}, + updateQueue.baseState, + ctor + ))); null !== derivedStateFromCatch && void 0 !== derivedStateFromCatch && - (renderExpirationTime = + ((renderExpirationTime = null === renderExpirationTime || void 0 === renderExpirationTime ? derivedStateFromCatch - : Object.assign({}, renderExpirationTime, derivedStateFromCatch)); + : Object.assign({}, renderExpirationTime, derivedStateFromCatch)), + (ctor = workInProgress.updateQueue), + null !== ctor && + (ctor.baseState = Object.assign( + {}, + ctor.baseState, + derivedStateFromCatch + ))); if ( !( oldProps !== newProps || @@ -2559,9 +2593,13 @@ function ReactFiberClassComponent( (oldProps === current.memoizedProps && oldContext === current.memoizedState) || (workInProgress.effectTag |= 4), + "function" !== typeof instance.getSnapshotBeforeUpdate || + (oldProps === current.memoizedProps && + oldContext === current.memoizedState) || + (workInProgress.effectTag |= 2048), !1 ); - (derivedStateFromProps = checkShouldComponentUpdate( + (derivedStateFromCatch = checkShouldComponentUpdate( workInProgress, oldProps, newProps, @@ -2569,9 +2607,9 @@ function ReactFiberClassComponent( renderExpirationTime, newUnmaskedContext )) - ? (("function" !== typeof instance.UNSAFE_componentWillUpdate && - "function" !== typeof instance.componentWillUpdate) || - "function" === typeof ctor.getDerivedStateFromProps || + ? (hasNewLifecycles || + ("function" !== typeof instance.UNSAFE_componentWillUpdate && + "function" !== typeof instance.componentWillUpdate) || ("function" === typeof instance.componentWillUpdate && instance.componentWillUpdate( newProps, @@ -2585,17 +2623,23 @@ function ReactFiberClassComponent( newUnmaskedContext )), "function" === typeof instance.componentDidUpdate && - (workInProgress.effectTag |= 4)) + (workInProgress.effectTag |= 4), + "function" === typeof instance.getSnapshotBeforeUpdate && + (workInProgress.effectTag |= 2048)) : ("function" !== typeof instance.componentDidUpdate || (oldProps === current.memoizedProps && oldContext === current.memoizedState) || (workInProgress.effectTag |= 4), + "function" !== typeof instance.getSnapshotBeforeUpdate || + (oldProps === current.memoizedProps && + oldContext === current.memoizedState) || + (workInProgress.effectTag |= 2048), memoizeProps(workInProgress, newProps), memoizeState(workInProgress, renderExpirationTime)); instance.props = newProps; instance.state = renderExpirationTime; instance.context = newUnmaskedContext; - return derivedStateFromProps; + return derivedStateFromCatch; } }; } @@ -3444,7 +3488,7 @@ function ReactFiberBeginWork( workInProgress, renderExpirationTime ) { - var context = workInProgress.type.context, + var context = workInProgress.type._context, newProps = workInProgress.pendingProps, oldProps = workInProgress.memoizedProps; if (!hasLegacyContextChanged() && oldProps === newProps) @@ -3610,7 +3654,8 @@ function ReactFiberBeginWork( ((props = callGetDerivedStateFromProps( workInProgress, fn, - props + props, + workInProgress.memoizedState )), null !== props && void 0 !== props && @@ -3881,43 +3926,33 @@ function ReactFiberBeginWork( renderExpirationTime ); case 12: - a: { - fn = workInProgress.type; - unmaskedContext = workInProgress.pendingProps; - updateQueue = workInProgress.memoizedProps; - props = fn._currentValue; - var changedBits = fn._changedBits; - if ( - hasLegacyContextChanged() || - 0 !== changedBits || - updateQueue !== unmaskedContext - ) { - workInProgress.memoizedProps = unmaskedContext; - var observedBits = unmaskedContext.unstable_observedBits; - if (void 0 === observedBits || null === observedBits) - observedBits = 1073741823; - workInProgress.stateNode = observedBits; - if (0 !== (changedBits & observedBits)) - propagateContextChange( - workInProgress, - fn, - changedBits, - renderExpirationTime - ); - else if ( - null !== updateQueue && - updateQueue.children === unmaskedContext.children - ) { - current = bailoutOnAlreadyFinishedWork(current, workInProgress); - break a; - } - renderExpirationTime = unmaskedContext.children; - renderExpirationTime = renderExpirationTime(props); - reconcileChildren(current, workInProgress, renderExpirationTime); - current = workInProgress.child; - } else - current = bailoutOnAlreadyFinishedWork(current, workInProgress); - } + fn = workInProgress.type; + unmaskedContext = workInProgress.pendingProps; + var oldProps = workInProgress.memoizedProps; + props = fn._currentValue; + updateQueue = fn._changedBits; + if ( + hasLegacyContextChanged() || + 0 !== updateQueue || + oldProps !== unmaskedContext + ) { + workInProgress.memoizedProps = unmaskedContext; + oldProps = unmaskedContext.unstable_observedBits; + if (void 0 === oldProps || null === oldProps) oldProps = 1073741823; + workInProgress.stateNode = oldProps; + 0 !== (updateQueue & oldProps) && + propagateContextChange( + workInProgress, + fn, + updateQueue, + renderExpirationTime + ); + renderExpirationTime = unmaskedContext.children; + renderExpirationTime = renderExpirationTime(props); + reconcileChildren(current, workInProgress, renderExpirationTime); + current = workInProgress.child; + } else + current = bailoutOnAlreadyFinishedWork(current, workInProgress); return current; default: invariant( @@ -4313,9 +4348,9 @@ function logError(boundary, errorInfo) { stack = errorInfo.stack; null === stack && (stack = getStackAddendumByWorkInProgressFiber(source)); null !== source && getComponentName(source); + source = null !== stack ? stack : ""; errorInfo = errorInfo.value; - stack = null !== stack ? stack : ""; - null !== boundary && getComponentName(boundary); + null !== boundary && 2 === boundary.tag && getComponentName(boundary); try { if (errorInfo instanceof Error) { var message = errorInfo.message, @@ -4325,13 +4360,13 @@ function logError(boundary, errorInfo) { errorToHandle.message = (message ? name + ": " + message : name) + "\n\nThis error is located at:" + - stack; + source; } catch (e) {} } else errorToHandle = "string" === typeof errorInfo - ? Error(errorInfo + "\n\nThis error is located at:" + stack) - : Error("Unspecified error at:" + stack); + ? 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); @@ -4360,12 +4395,12 @@ function ReactFiberCommitWork( switch (current.tag) { case 2: safelyDetachRef(current); - var _instance6 = current.stateNode; - if ("function" === typeof _instance6.componentWillUnmount) + var _instance7 = current.stateNode; + if ("function" === typeof _instance7.componentWillUnmount) try { - (_instance6.props = current.memoizedProps), - (_instance6.state = current.memoizedState), - _instance6.componentWillUnmount(); + (_instance7.props = current.memoizedProps), + (_instance7.state = current.memoizedState), + _instance7.componentWillUnmount(); } catch (unmountError) { captureError(current, unmountError); } @@ -4475,6 +4510,34 @@ function ReactFiberCommitWork( 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." + ); + } + }, commitResetTextContent: function(current) { resetTextContent(current.stateNode); }, @@ -4580,8 +4643,8 @@ function ReactFiberCommitWork( case 2: break; case 5: - var _instance7 = finishedWork.stateNode; - if (null != _instance7) { + var _instance8 = finishedWork.stateNode; + if (null != _instance8) { var newProps = finishedWork.memoizedProps; current = null !== current ? current.memoizedProps : newProps; var type = finishedWork.type, @@ -4589,7 +4652,7 @@ function ReactFiberCommitWork( finishedWork.updateQueue = null; null !== updatePayload && commitUpdate( - _instance7, + _instance8, updatePayload, type, current, @@ -4603,11 +4666,11 @@ function ReactFiberCommitWork( 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; + _instance8 = finishedWork.memoizedProps; commitTextUpdate( finishedWork.stateNode, - null !== current ? current.memoizedProps : _instance7, - _instance7 + null !== current ? current.memoizedProps : _instance8, + _instance8 ); break; case 3: @@ -4633,7 +4696,11 @@ function ReactFiberCommitWork( current = current.memoizedState; finishedRoot.props = finishedWork.memoizedProps; finishedRoot.state = finishedWork.memoizedState; - finishedRoot.componentDidUpdate(prevProps, current); + finishedRoot.componentDidUpdate( + prevProps, + current, + finishedRoot.__reactInternalSnapshotBeforeUpdate + ); } finishedWork = finishedWork.updateQueue; null !== finishedWork && commitCallbacks(finishedWork, finishedRoot); @@ -4695,9 +4762,12 @@ function ReactFiberCommitWork( onUncaughtError.state = finishedWork.memoizedState; for (ctor = 0; ctor < capturedErrors.length; ctor++) { updateQueue = capturedErrors[ctor]; - var _error = updateQueue.value; + var _error = updateQueue.value, + stack = updateQueue.stack; logError(finishedWork, updateQueue); - onUncaughtError.componentDidCatch(_error); + onUncaughtError.componentDidCatch(_error, { + componentStack: null !== stack ? stack : "" + }); } break; case 3: @@ -4723,13 +4793,13 @@ function ReactFiberCommitWork( commitAttachRef: function(finishedWork) { var ref = finishedWork.ref; if (null !== ref) { - var _instance5 = finishedWork.stateNode; + var _instance6 = finishedWork.stateNode; switch (finishedWork.tag) { case 5: - finishedWork = getPublicInstance(_instance5); + finishedWork = getPublicInstance(_instance6); break; default: - finishedWork = _instance5; + finishedWork = _instance6; } "function" === typeof ref ? ref(finishedWork) @@ -4780,8 +4850,10 @@ function ReactFiberHostContext(config, stack) { }, pushHostContainer: function(fiber, nextRootInstance) { push(rootInstanceStackCursor, nextRootInstance, fiber); - nextRootInstance = getRootHostContext(nextRootInstance); push(contextFiberStackCursor, fiber, fiber); + push(contextStackCursor, NO_CONTEXT, fiber); + nextRootInstance = getRootHostContext(nextRootInstance); + pop(contextStackCursor, fiber); push(contextStackCursor, nextRootInstance, fiber); }, pushHostContext: function(fiber) { @@ -5088,7 +5160,7 @@ function ReactFiberNewContext(stack) { changedBitsCursor = createCursor(0); return { pushProvider: function(providerFiber) { - var context = providerFiber.type.context; + var context = providerFiber.type._context; push(changedBitsCursor, context._changedBits, providerFiber); push(valueCursor, context._currentValue, providerFiber); push(providerCursor, providerFiber, providerFiber); @@ -5101,7 +5173,7 @@ function ReactFiberNewContext(stack) { pop(providerCursor, providerFiber); pop(valueCursor, providerFiber); pop(changedBitsCursor, providerFiber); - providerFiber = providerFiber.type.context; + providerFiber = providerFiber.type._context; providerFiber._currentValue = currentValue; providerFiber._changedBits = changedBits; } @@ -5214,7 +5286,7 @@ function ReactFiberScheduler(config) { workInProgress$jscomp$0 = unwindWork(workInProgress$jscomp$0); if (null !== workInProgress$jscomp$0) return ( - (workInProgress$jscomp$0.effectTag &= 511), workInProgress$jscomp$0 + (workInProgress$jscomp$0.effectTag &= 2559), workInProgress$jscomp$0 ); null !== returnFiber && ((returnFiber.firstEffect = returnFiber.lastEffect = null), @@ -5378,7 +5450,7 @@ function ReactFiberScheduler(config) { 0 !== nextRenderExpirationTime && expirationTime < nextRenderExpirationTime && resetStack(); - (nextRoot === root && isWorking) || + (isWorking && !isCommitting && nextRoot === root) || requestWork(root, expirationTime); nestedUpdateCount > NESTED_UPDATE_LIMIT && invariant( @@ -5442,7 +5514,7 @@ function ReactFiberScheduler(config) { (nextFlushedExpirationTime = 1), performWorkOnRoot(root, 1, !1)) : 1 === expirationTime - ? performWork(1, !1, null) + ? performSyncWork() : scheduleCallbackWithExpiration(expirationTime)); } function findHighestPriorityRoot() { @@ -5502,6 +5574,9 @@ function ReactFiberScheduler(config) { function performAsyncWork(dl) { performWork(0, !0, dl); } + function performSyncWork() { + performWork(1, !1, null); + } function performWork(minExpirationTime, isAsync, dl) { deadline = dl; findHighestPriorityRoot(); @@ -5624,6 +5699,25 @@ function ReactFiberScheduler(config) { for (nextEffect = firstEffect; null !== nextEffect; ) { var didError = !1, error = void 0; + try { + for (; null !== nextEffect; ) + nextEffect.effectTag & 2048 && + commitBeforeMutationLifeCycles(nextEffect.alternate, nextEffect), + (nextEffect = nextEffect.nextEffect); + } catch (e) { + (didError = !0), (error = e); + } + didError && + (invariant( + null !== nextEffect, + "Should have next effect. This error is likely caused by a bug in React. Please file an issue." + ), + onCommitPhaseError(nextEffect, error), + null !== nextEffect && (nextEffect = nextEffect.nextEffect)); + } + for (nextEffect = firstEffect; null !== nextEffect; ) { + didError = !1; + error = void 0; try { for (; null !== nextEffect; ) { var effectTag = nextEffect.effectTag; @@ -5764,7 +5858,9 @@ function ReactFiberScheduler(config) { }, recalculateCurrentTime ); - var commitResetTextContent = hostContext.commitResetTextContent, + var commitBeforeMutationLifeCycles = + hostContext.commitBeforeMutationLifeCycles, + commitResetTextContent = hostContext.commitResetTextContent, commitPlacement = hostContext.commitPlacement, commitDeletion = hostContext.commitDeletion, commitWork = hostContext.commitWork, @@ -5819,7 +5915,10 @@ function ReactFiberScheduler(config) { !isRendering, "work.commit(): Cannot commit while already rendering. This likely means you attempted to commit from inside a lifecycle method." ); + nextFlushedRoot = root; + nextFlushedExpirationTime = expirationTime; performWorkOnRoot(root, expirationTime, !1); + performSyncWork(); finishRendering(); }, batchedUpdates: function(fn, a) { @@ -5830,7 +5929,7 @@ function ReactFiberScheduler(config) { } finally { (isBatchingUpdates = previousIsBatchingUpdates) || isRendering || - performWork(1, !1, null); + performSyncWork(); } }, unbatchedUpdates: function(fn, a) { @@ -5854,8 +5953,7 @@ function ReactFiberScheduler(config) { try { return syncUpdates(fn, a); } finally { - (isBatchingUpdates = previousIsBatchingUpdates), - performWork(1, !1, null); + (isBatchingUpdates = previousIsBatchingUpdates), performSyncWork(); } }, flushControlled: function(fn) { @@ -5896,7 +5994,7 @@ function ReactFiberScheduler(config) { (isBatchingInteractiveUpdates = previousIsBatchingInteractiveUpdates), (isBatchingUpdates = previousIsBatchingUpdates) || isRendering || - performWork(1, !1, null); + performSyncWork(); } }, flushInteractiveUpdates: function() { @@ -6128,7 +6226,8 @@ var ReactFiberReconciler$2 = Object.freeze({ default: ReactFiberReconciler$1 }), frameDeadlineObject = { timeRemaining: function() { return frameDeadline - now(); - } + }, + didTimeout: !1 }; function setTimeoutCallback() { frameDeadline = now() + 5; @@ -6462,7 +6561,7 @@ NativeRenderer.injectIntoDevTools({ findFiberByHostInstance: getInstanceFromTag, getInspectorDataForViewTag: getInspectorDataForViewTag, bundleType: 0, - version: "16.3.0-alpha.2", + version: "16.3.1", rendererPackageName: "react-native-renderer" }); var ReactNativeRenderer$2 = Object.freeze({ default: ReactNativeRenderer }), diff --git a/Libraries/Renderer/shims/ReactFabric.js b/Libraries/Renderer/shims/ReactFabric.js index 6ab336bf1..4162ca62f 100644 --- a/Libraries/Renderer/shims/ReactFabric.js +++ b/Libraries/Renderer/shims/ReactFabric.js @@ -25,4 +25,3 @@ if (__DEV__) { BatchedBridge.registerCallableModule('ReactFabric', ReactFabric); module.exports = (ReactFabric: ReactNativeType); - diff --git a/Libraries/Renderer/shims/ReactTypes.js b/Libraries/Renderer/shims/ReactTypes.js index f6a56ccc9..689ed18bf 100644 --- a/Libraries/Renderer/shims/ReactTypes.js +++ b/Libraries/Renderer/shims/ReactTypes.js @@ -62,7 +62,7 @@ export type ReactProvider = { export type ReactProviderType = { $$typeof: Symbol | number, - context: ReactContext, + _context: ReactContext, }; export type ReactConsumer = { @@ -72,7 +72,7 @@ export type ReactConsumer = { ref: null, props: { children: (value: T) => ReactNodeList, - bits?: number, + unstable_observedBits?: number, }, }; diff --git a/package.json b/package.json index d15a462f1..4f4f55845 100644 --- a/package.json +++ b/package.json @@ -142,7 +142,7 @@ "react-native": "local-cli/wrong-react-native.js" }, "peerDependencies": { - "react": "^16.3.0-alpha.2" + "react": "16.3.1" }, "dependencies": { "absolute-path": "^0.0.0", @@ -219,8 +219,8 @@ "jest": "23.0.0-alpha.4", "jest-junit": "3.6.0", "prettier": "1.9.1", - "react": "^16.3.0-alpha.2", - "react-test-renderer": "^16.3.0-alpha.2", + "react": "16.3.1", + "react-test-renderer": "16.3.1", "shelljs": "^0.7.8", "sinon": "^2.2.0" }