From 5e80d95e034259af8c41b50756a623756cc81a77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ramos?= Date: Fri, 9 Feb 2018 16:01:29 -0800 Subject: [PATCH] React sync for revisions 4eed18d...467b103 Reviewed By: bvaughn Differential Revision: D6953225 fbshipit-source-id: f96e3cec57cce397d46d49115dd3734a33427992 --- Libraries/Renderer/REVISION | 2 +- Libraries/Renderer/ReactFabric-dev.js | 284 +++---- Libraries/Renderer/ReactFabric-prod.js | 729 ++++++++---------- Libraries/Renderer/ReactNativeRenderer-dev.js | 263 ++++--- .../Renderer/ReactNativeRenderer-prod.js | 94 ++- Libraries/Renderer/shims/ReactFeatureFlags.js | 2 +- Libraries/Renderer/shims/ReactTypes.js | 4 + 7 files changed, 688 insertions(+), 690 deletions(-) diff --git a/Libraries/Renderer/REVISION b/Libraries/Renderer/REVISION index 69753c2a9ed2e2..981ea0ea492919 100644 --- a/Libraries/Renderer/REVISION +++ b/Libraries/Renderer/REVISION @@ -1 +1 @@ -4eed18dd72cb811de11bd34b8ff86e4d193c7d4e \ No newline at end of file +467b1034ce8af6807e11deb9dfeca4d4e922ed82 \ No newline at end of file diff --git a/Libraries/Renderer/ReactFabric-dev.js b/Libraries/Renderer/ReactFabric-dev.js index 68d381f6aeadb7..475dd17d22ae91 100644 --- a/Libraries/Renderer/ReactFabric-dev.js +++ b/Libraries/Renderer/ReactFabric-dev.js @@ -289,78 +289,6 @@ var rethrowCaughtError = function() { } }; -/** - * Forked from fbjs/warning: - * https://github.com/facebook/fbjs/blob/e66ba20ad5be433eb54423f2b097d829324d9de6/packages/fbjs/src/__forks__/warning.js - * - * Only change is we use console.warn instead of console.error, - * and do nothing when 'console' is not supported. - * This really simplifies the code. - * --- - * Similar to invariant but only logs a warning if the condition is not met. - * This can be used to log issues in development environments in critical - * paths. Removing the logging code for production environments will keep the - * same logic and follow the same code paths. - */ - -var lowPriorityWarning = function() {}; - -{ - var printWarning = function(format) { - for ( - var _len = arguments.length, - args = Array(_len > 1 ? _len - 1 : 0), - _key = 1; - _key < _len; - _key++ - ) { - args[_key - 1] = arguments[_key]; - } - - var argIndex = 0; - var message = - "Warning: " + - format.replace(/%s/g, function() { - return args[argIndex++]; - }); - if (typeof console !== "undefined") { - console.warn(message); - } - try { - // --- Welcome to debugging React --- - // This error was thrown as a convenience so that you can use this stack - // to find the callsite that caused this warning to fire. - throw new Error(message); - } catch (x) {} - }; - - lowPriorityWarning = function(condition, format) { - if (format === undefined) { - throw new Error( - "`warning(condition, format, ...args)` requires a warning " + - "message argument" - ); - } - if (!condition) { - for ( - var _len2 = arguments.length, - args = Array(_len2 > 2 ? _len2 - 2 : 0), - _key2 = 2; - _key2 < _len2; - _key2++ - ) { - args[_key2 - 2] = arguments[_key2]; - } - - printWarning.apply(undefined, [format].concat(args)); - } - }; -} - -var lowPriorityWarning$1 = lowPriorityWarning; - -var shouldWarnOnInjection = false; - /** * Injectable ordering of event plugins. */ @@ -546,21 +474,6 @@ function injectEventPluginOrder(injectedEventPluginOrder) { * @see {EventPluginHub.injection.injectEventPluginsByName} */ function injectEventPluginsByName(injectedNamesToPlugins) { - { - if (shouldWarnOnInjection) { - var names = Object.keys(injectedNamesToPlugins).join(", "); - lowPriorityWarning$1( - false, - "Injecting custom event plugins (%s) is deprecated " + - "and will not work in React 17+. Please update your code " + - "to not depend on React internals. The stack trace for this " + - "warning should reveal the library that is using them. " + - "See https://github.com/facebook/react/issues/11689 for a discussion.", - names - ); - } - } - var isOrderingDirty = false; for (var pluginName in injectedNamesToPlugins) { if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) { @@ -3076,7 +2989,7 @@ var ReactGlobalSharedState = Object.freeze({ // TODO: this is special because it gets imported during build. -var ReactVersion = "16.2.0"; +var ReactVersion = "16.3.0-alpha.0"; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { @@ -4709,27 +4622,16 @@ var ReactDebugCurrentFiber = { getCurrentFiberStackAddendum: getCurrentFiberStackAddendum }; -// Exports ReactDOM.createRoot +var debugRenderPhaseSideEffects = false; +var debugRenderPhaseSideEffectsForStrictMode = false; var enableUserTimingAPI = true; +var warnAboutDeprecatedLifecycles = false; -// Mutating mode (React DOM, React ART, React Native): -var enableMutatingReconciler = true; -// Experimental noop mode (currently unused): +// React Fabric uses persistent reconciler. +var enableMutatingReconciler = false; var enableNoopReconciler = false; -// Experimental persistent mode (Fabric): var enablePersistentReconciler = true; -// Helps identify side effects in begin-phase lifecycle hooks and setState reducers: -var debugRenderPhaseSideEffects = false; - -// In some cases, StrictMode should also double-render lifecycles. -// This can be confusing for tests though, -// And it can be bad for performance in production. -// This feature flag can be used to control the behavior: -var debugRenderPhaseSideEffectsForStrictMode = true; - -// Warn about deprecated, async-unsafe lifecycles; relates to RFC #6: -var warnAboutDeprecatedLifecycles = false; // Only used in www builds. @@ -5855,6 +5757,76 @@ function onCommitUnmount(fiber) { } } +/** + * Forked from fbjs/warning: + * https://github.com/facebook/fbjs/blob/e66ba20ad5be433eb54423f2b097d829324d9de6/packages/fbjs/src/__forks__/warning.js + * + * Only change is we use console.warn instead of console.error, + * and do nothing when 'console' is not supported. + * This really simplifies the code. + * --- + * Similar to invariant but only logs a warning if the condition is not met. + * This can be used to log issues in development environments in critical + * paths. Removing the logging code for production environments will keep the + * same logic and follow the same code paths. + */ + +var lowPriorityWarning = function() {}; + +{ + var printWarning = function(format) { + for ( + var _len = arguments.length, + args = Array(_len > 1 ? _len - 1 : 0), + _key = 1; + _key < _len; + _key++ + ) { + args[_key - 1] = arguments[_key]; + } + + var argIndex = 0; + var message = + "Warning: " + + format.replace(/%s/g, function() { + return args[argIndex++]; + }); + if (typeof console !== "undefined") { + console.warn(message); + } + try { + // --- Welcome to debugging React --- + // This error was thrown as a convenience so that you can use this stack + // to find the callsite that caused this warning to fire. + throw new Error(message); + } catch (x) {} + }; + + lowPriorityWarning = function(condition, format) { + if (format === undefined) { + throw new Error( + "`warning(condition, format, ...args)` requires a warning " + + "message argument" + ); + } + if (!condition) { + for ( + var _len2 = arguments.length, + args = Array(_len2 > 2 ? _len2 - 2 : 0), + _key2 = 2; + _key2 < _len2; + _key2++ + ) { + args[_key2 - 2] = arguments[_key2]; + } + + printWarning.apply(undefined, [format].concat(args)); + } + }; +} + +var lowPriorityWarning$1 = lowPriorityWarning; + var ReactStrictModeWarnings = { discardPendingWarnings: function() {}, flushPendingDeprecationWarnings: function() {}, @@ -5962,7 +5934,7 @@ var ReactStrictModeWarnings = { .sort() .join(", "); - warning( + lowPriorityWarning$1( false, "componentWillMount is deprecated and will be removed in the next major version. " + "Use componentDidMount instead. As a temporary workaround, " + @@ -5987,7 +5959,7 @@ var ReactStrictModeWarnings = { .sort() .join(", "); - warning( + lowPriorityWarning$1( false, "componentWillReceiveProps is deprecated and will be removed in the next major version. " + "Use static getDerivedStateFromProps instead." + @@ -6011,7 +5983,7 @@ var ReactStrictModeWarnings = { .sort() .join(", "); - warning( + lowPriorityWarning$1( false, "componentWillUpdate is deprecated and will be removed in the next major version. " + "Use componentDidUpdate instead. As a temporary workaround, " + @@ -7284,12 +7256,15 @@ var getCurrentFiberStackAddendum$1 = ReactDebugCurrentFiber.getCurrentFiberStackAddendum; var didWarnAboutMaps = void 0; +var didWarnAboutStringRefInStrictMode = void 0; var ownerHasKeyUseWarning = void 0; var ownerHasFunctionTypeWarning = void 0; var warnForMissingKey = function(child) {}; { didWarnAboutMaps = false; + didWarnAboutStringRefInStrictMode = {}; + /** * Warn if there's no key explicitly set on dynamic arrays of children or * object keys are not valid. This allows us to keep track of children between @@ -7334,9 +7309,33 @@ var warnForMissingKey = function(child) {}; var isArray$1 = Array.isArray; -function coerceRef(current, element) { +function coerceRef(returnFiber, current, element) { var mixedRef = element.ref; - if (mixedRef !== null && typeof mixedRef !== "function") { + if ( + mixedRef !== null && + typeof mixedRef !== "function" && + typeof mixedRef !== "object" + ) { + { + if (returnFiber.mode & StrictMode) { + var componentName = getComponentName(returnFiber) || "Component"; + if (!didWarnAboutStringRefInStrictMode[componentName]) { + warning( + false, + 'A string ref, "%s", has been found within a strict mode tree. ' + + "String refs are a source of potential bugs and should be avoided. " + + "We recommend using createRef() instead." + + "\n%s" + + "\n\nLearn more about using refs safely here:" + + "\nhttps://fb.me/react-strict-mode-string-ref", + mixedRef, + getStackAddendumByWorkInProgressFiber(returnFiber) + ); + didWarnAboutStringRefInStrictMode[componentName] = true; + } + } + } + if (element._owner) { var owner = element._owner; var inst = void 0; @@ -7557,7 +7556,7 @@ function ChildReconciler(shouldTrackSideEffects) { if (current !== null && current.type === element.type) { // Move based on index var existing = useFiber(current, element.props, expirationTime); - existing.ref = coerceRef(current, element); + existing.ref = coerceRef(returnFiber, current, element); existing["return"] = returnFiber; { existing._debugSource = element._source; @@ -7571,7 +7570,7 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime ); - created.ref = coerceRef(current, element); + created.ref = coerceRef(returnFiber, current, element); created["return"] = returnFiber; return created; } @@ -7641,7 +7640,7 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime ); - _created.ref = coerceRef(null, newChild); + _created.ref = coerceRef(returnFiber, null, newChild); _created["return"] = returnFiber; return _created; } @@ -8275,7 +8274,7 @@ function ChildReconciler(shouldTrackSideEffects) { : element.props, expirationTime ); - existing.ref = coerceRef(child, element); + existing.ref = coerceRef(returnFiber, child, element); existing["return"] = returnFiber; { existing._debugSource = element._source; @@ -8307,7 +8306,7 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime ); - _created4.ref = coerceRef(currentFirstChild, element); + _created4.ref = coerceRef(returnFiber, currentFirstChild, element); _created4["return"] = returnFiber; return _created4; } @@ -8514,6 +8513,8 @@ function cloneChildFibers(current, workInProgress) { newChild.sibling = null; } +var changedBitsStack = []; +var currentValueStack = []; var stack = []; var index$1 = -1; @@ -8524,9 +8525,11 @@ var rendererSigil = void 0; } function pushProvider(providerFiber) { + var context = providerFiber.type.context; index$1 += 1; + changedBitsStack[index$1] = context.changedBits; + currentValueStack[index$1] = context.currentValue; stack[index$1] = providerFiber; - var context = providerFiber.type.context; context.currentValue = providerFiber.pendingProps.value; context.changedBits = providerFiber.stateNode; @@ -8548,17 +8551,15 @@ function popProvider(providerFiber) { "Unexpected pop." ); } + var changedBits = changedBitsStack[index$1]; + var currentValue = currentValueStack[index$1]; + changedBitsStack[index$1] = null; + currentValueStack[index$1] = null; stack[index$1] = null; index$1 -= 1; var context = providerFiber.type.context; - if (index$1 < 0) { - context.currentValue = context.defaultValue; - context.changedBits = 0; - } else { - var previousProviderFiber = stack[index$1]; - context.currentValue = previousProviderFiber.pendingProps.value; - context.changedBits = previousProviderFiber.stateNode; - } + context.currentValue = currentValue; + context.changedBits = changedBits; } function resetProviderStack() { @@ -8567,6 +8568,8 @@ function resetProviderStack() { var context = providerFiber.type.context; context.currentValue = context.defaultValue; context.changedBits = 0; + changedBitsStack[i] = null; + currentValueStack[i] = null; stack[i] = null; { context._currentRenderer = null; @@ -8689,7 +8692,10 @@ var ReactFiberBeginWork = function( function markRef(current, workInProgress) { var ref = workInProgress.ref; - if (ref !== null && (!current || current.ref !== ref)) { + if ( + (current === null && ref !== null) || + (current !== null && current.ref !== ref) + ) { // Schedule a Ref effect workInProgress.effectTag |= Ref; } @@ -10159,12 +10165,16 @@ var ReactFiberCommitWork = function(config, captureError) { function safelyDetachRef(current) { var ref = current.ref; if (ref !== null) { - { - invokeGuardedCallback$3(null, ref, null, null); - if (hasCaughtError$1()) { - var refError = clearCaughtError$1(); - captureError(current, refError); + if (typeof ref === "function") { + { + invokeGuardedCallback$3(null, ref, null, null); + if (hasCaughtError$1()) { + var refError = clearCaughtError$1(); + captureError(current, refError); + } } + } else { + ref.value = null; } } } @@ -10251,12 +10261,18 @@ var ReactFiberCommitWork = function(config, captureError) { var ref = finishedWork.ref; if (ref !== null) { var instance = finishedWork.stateNode; + var instanceToUse = void 0; switch (finishedWork.tag) { case HostComponent: - ref(getPublicInstance(instance)); + instanceToUse = getPublicInstance(instance); break; default: - ref(instance); + instanceToUse = instance; + } + if (typeof ref === "function") { + ref(instanceToUse); + } else { + ref.value = instanceToUse; } } } @@ -10264,7 +10280,11 @@ var ReactFiberCommitWork = function(config, captureError) { function commitDetachRef(current) { var currentRef = current.ref; if (currentRef !== null) { - currentRef(null); + if (typeof currentRef === "function") { + currentRef(null); + } else { + currentRef.value = null; + } } } diff --git a/Libraries/Renderer/ReactFabric-prod.js b/Libraries/Renderer/ReactFabric-prod.js index ebac6f4f4e9af8..d4d20d3ac85504 100644 --- a/Libraries/Renderer/ReactFabric-prod.js +++ b/Libraries/Renderer/ReactFabric-prod.js @@ -2494,9 +2494,13 @@ function ReactFiberClassComponent( }; } var isArray$1 = Array.isArray; -function coerceRef(current, element) { - var mixedRef = element.ref; - if (null !== mixedRef && "function" !== typeof mixedRef) { +function coerceRef(returnFiber, current, element) { + returnFiber = element.ref; + if ( + null !== returnFiber && + "function" !== typeof returnFiber && + "object" !== typeof returnFiber + ) { if (element._owner) { element = element._owner; var inst = void 0; @@ -2509,9 +2513,9 @@ function coerceRef(current, element) { invariant( inst, "Missing owner for string ref %s. This error is likely caused by a bug in React. Please file an issue.", - mixedRef + returnFiber ); - var stringRef = "" + mixedRef; + var stringRef = "" + returnFiber; if ( null !== current && null !== current.ref && @@ -2526,16 +2530,16 @@ function coerceRef(current, element) { return current; } invariant( - "string" === typeof mixedRef, + "string" === typeof returnFiber, "Expected ref to be a function or a string." ); invariant( element._owner, "Element ref was specified as a string (%s) but no owner was set. This could happen for one of the following reasons:\n1. You may be adding a ref to a functional component\n2. You may be adding a ref to a component that was not created inside a component's render method\n3. You have multiple copies of React loaded\nSee https://fb.me/react-refs-must-have-owner for more information.", - mixedRef + returnFiber ); } - return mixedRef; + return returnFiber; } function throwOnInvalidObjectType(returnFiber, newChild) { "textarea" !== returnFiber.type && @@ -2620,7 +2624,7 @@ function ChildReconciler(shouldTrackSideEffects) { if (null !== current && current.type === element.type) return ( (expirationTime = useFiber(current, element.props, expirationTime)), - (expirationTime.ref = coerceRef(current, element)), + (expirationTime.ref = coerceRef(returnFiber, current, element)), (expirationTime["return"] = returnFiber), expirationTime ); @@ -2629,7 +2633,7 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime ); - expirationTime.ref = coerceRef(current, element); + expirationTime.ref = coerceRef(returnFiber, current, element); expirationTime["return"] = returnFiber; return expirationTime; } @@ -2689,7 +2693,7 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime )), - (expirationTime.ref = coerceRef(null, newChild)), + (expirationTime.ref = coerceRef(returnFiber, null, newChild)), (expirationTime["return"] = returnFiber), expirationTime ); @@ -3034,7 +3038,11 @@ function ChildReconciler(shouldTrackSideEffects) { : newChild.props, expirationTime ); - currentFirstChild.ref = coerceRef(isObject, newChild); + currentFirstChild.ref = coerceRef( + returnFiber, + isObject, + newChild + ); currentFirstChild["return"] = returnFiber; returnFiber = currentFirstChild; break a; @@ -3059,7 +3067,11 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime )), - (expirationTime.ref = coerceRef(currentFirstChild, newChild)), + (expirationTime.ref = coerceRef( + returnFiber, + currentFirstChild, + newChild + )), (expirationTime["return"] = returnFiber), (returnFiber = expirationTime)); } @@ -3155,27 +3167,29 @@ function ChildReconciler(shouldTrackSideEffects) { } var reconcileChildFibers = ChildReconciler(!0), mountChildFibers = ChildReconciler(!1), + changedBitsStack = [], + currentValueStack = [], stack = [], index$1 = -1; function pushProvider(providerFiber) { + var context = providerFiber.type.context; index$1 += 1; + changedBitsStack[index$1] = context.changedBits; + currentValueStack[index$1] = context.currentValue; stack[index$1] = providerFiber; - var context = providerFiber.type.context; context.currentValue = providerFiber.pendingProps.value; context.changedBits = providerFiber.stateNode; } function popProvider(providerFiber) { + var changedBits = changedBitsStack[index$1], + currentValue = currentValueStack[index$1]; + changedBitsStack[index$1] = null; + currentValueStack[index$1] = null; stack[index$1] = null; --index$1; providerFiber = providerFiber.type.context; - if (0 > index$1) - (providerFiber.currentValue = providerFiber.defaultValue), - (providerFiber.changedBits = 0); - else { - var previousProviderFiber = stack[index$1]; - providerFiber.currentValue = previousProviderFiber.pendingProps.value; - providerFiber.changedBits = previousProviderFiber.stateNode; - } + providerFiber.currentValue = currentValue; + providerFiber.changedBits = changedBits; } function ReactFiberBeginWork( config, @@ -3203,9 +3217,11 @@ function ReactFiberBeginWork( } function markRef(current, workInProgress) { var ref = workInProgress.ref; - null === ref || - (current && current.ref === ref) || - (workInProgress.effectTag |= 128); + if ( + (null === current && null !== ref) || + (null !== current && current.ref !== ref) + ) + workInProgress.effectTag |= 128; } function finishClassComponent( current, @@ -3738,6 +3754,25 @@ function ReactFiberCompleteWork(config, hostContext, hydrationContext) { function markUpdate(workInProgress) { workInProgress.effectTag |= 4; } + function appendAllChildren(parent, workInProgress) { + for (var node = workInProgress.child; null !== node; ) { + if (5 === node.tag || 6 === node.tag) + appendInitialChild(parent, node.stateNode); + else if (4 !== node.tag && null !== node.child) { + node.child["return"] = node; + node = node.child; + continue; + } + if (node === workInProgress) break; + for (; null === node.sibling; ) { + if (null === node["return"] || node["return"] === workInProgress) + return; + node = node["return"]; + } + node.sibling["return"] = node["return"]; + node = node.sibling; + } + } var createInstance = config.createInstance, createTextInstance = config.createTextInstance, appendInitialChild = config.appendInitialChild, @@ -3756,18 +3791,93 @@ function ReactFiberCompleteWork(config, hostContext, hydrationContext) { updateHostContainer = void 0, updateHostComponent = void 0, updateHostText = void 0; - config.mutation - ? ((updateHostContainer = function() {}), - (updateHostComponent = function(current, workInProgress, updatePayload) { - (workInProgress.updateQueue = updatePayload) && + if (config.mutation) invariant(!1, "Mutating reconciler is disabled."); + else if (persistence) { + var cloneInstance = persistence.cloneInstance, + createContainerChildSet = persistence.createContainerChildSet, + appendChildToContainerChildSet = + persistence.appendChildToContainerChildSet, + finalizeContainerChildren = persistence.finalizeContainerChildren; + updateHostContainer = function(workInProgress) { + var portalOrRoot = workInProgress.stateNode; + if (null !== workInProgress.firstEffect) { + var container = portalOrRoot.containerInfo, + newChildSet = createContainerChildSet(container); + finalizeContainerChildren(container, newChildSet) && markUpdate(workInProgress); - }), - (updateHostText = function(current, workInProgress, oldText, newText) { - oldText !== newText && markUpdate(workInProgress); - })) - : persistence - ? invariant(!1, "Persistent reconciler is disabled.") - : invariant(!1, "Noop reconciler is disabled."); + portalOrRoot.pendingChildren = newChildSet; + a: for (portalOrRoot = workInProgress.child; null !== portalOrRoot; ) { + if (5 === portalOrRoot.tag || 6 === portalOrRoot.tag) + appendChildToContainerChildSet(newChildSet, portalOrRoot.stateNode); + else if (4 !== portalOrRoot.tag && null !== portalOrRoot.child) { + portalOrRoot.child["return"] = portalOrRoot; + portalOrRoot = portalOrRoot.child; + continue; + } + if (portalOrRoot === workInProgress) break a; + for (; null === portalOrRoot.sibling; ) { + if ( + null === portalOrRoot["return"] || + portalOrRoot["return"] === workInProgress + ) + break a; + portalOrRoot = portalOrRoot["return"]; + } + portalOrRoot.sibling["return"] = portalOrRoot["return"]; + portalOrRoot = portalOrRoot.sibling; + } + markUpdate(workInProgress); + } + }; + updateHostComponent = function( + current, + workInProgress, + updatePayload, + type, + oldProps, + newProps, + rootContainerInstance, + currentHostContext + ) { + var childrenUnchanged = null === workInProgress.firstEffect; + current = current.stateNode; + childrenUnchanged && null === updatePayload + ? (workInProgress.stateNode = current) + : ((updatePayload = cloneInstance( + current, + updatePayload, + type, + oldProps, + newProps, + workInProgress, + childrenUnchanged, + workInProgress.stateNode + )), + finalizeInitialChildren( + updatePayload, + type, + newProps, + rootContainerInstance, + currentHostContext + ) && markUpdate(workInProgress), + (workInProgress.stateNode = updatePayload), + childrenUnchanged + ? markUpdate(workInProgress) + : appendAllChildren(updatePayload, workInProgress)); + }; + updateHostText = function(current, workInProgress, oldText, newText) { + oldText !== newText && + ((current = getRootHostContainer()), + (oldText = getHostContext()), + (workInProgress.stateNode = createTextInstance( + newText, + current, + oldText, + workInProgress + )), + markUpdate(workInProgress)); + }; + } else invariant(!1, "Noop reconciler is disabled."); return { completeWork: function(current, workInProgress, renderExpirationTime) { var newProps = workInProgress.pendingProps; @@ -3826,60 +3936,28 @@ function ReactFiberCompleteWork(config, hostContext, hydrationContext) { null ); current = getHostContext(); - if (popHydrationState(workInProgress)) - prepareToHydrateHostInstance( - workInProgress, - renderExpirationTime, - current - ) && markUpdate(workInProgress); - else { - oldProps = createInstance( - type, - newProps, - renderExpirationTime, - current, - workInProgress - ); - a: for ( - currentHostContext = workInProgress.child; - null !== currentHostContext; - - ) { - if ( - 5 === currentHostContext.tag || - 6 === currentHostContext.tag - ) - appendInitialChild(oldProps, currentHostContext.stateNode); - else if ( - 4 !== currentHostContext.tag && - null !== currentHostContext.child - ) { - currentHostContext.child["return"] = currentHostContext; - currentHostContext = currentHostContext.child; - continue; - } - if (currentHostContext === workInProgress) break; - for (; null === currentHostContext.sibling; ) { - if ( - null === currentHostContext["return"] || - currentHostContext["return"] === workInProgress - ) - break a; - currentHostContext = currentHostContext["return"]; - } - currentHostContext.sibling["return"] = - currentHostContext["return"]; - currentHostContext = currentHostContext.sibling; - } - finalizeInitialChildren( - oldProps, - type, - newProps, - renderExpirationTime, - current - ) && markUpdate(workInProgress); - workInProgress.stateNode = oldProps; - } + popHydrationState(workInProgress) + ? prepareToHydrateHostInstance( + workInProgress, + renderExpirationTime, + current + ) && markUpdate(workInProgress) + : ((oldProps = createInstance( + type, + newProps, + renderExpirationTime, + current, + workInProgress + )), + appendAllChildren(oldProps, workInProgress), + finalizeInitialChildren( + oldProps, + type, + newProps, + renderExpirationTime, + current + ) && markUpdate(workInProgress), + (workInProgress.stateNode = oldProps)); null !== workInProgress.ref && (workInProgress.effectTag |= 128); } return null; @@ -3991,350 +4069,187 @@ function ReactFiberCommitWork(config, captureError) { function safelyDetachRef(current) { var ref = current.ref; if (null !== ref) - try { - ref(null); - } catch (refError) { - captureError(current, refError); - } + if ("function" === typeof ref) + try { + ref(null); + } catch (refError) { + captureError(current, refError); + } + else ref.value = null; } - function commitUnmount(current) { - "function" === typeof onCommitUnmount && onCommitUnmount(current); - switch (current.tag) { + function commitLifeCycles(current, finishedWork) { + switch (finishedWork.tag) { case 2: - safelyDetachRef(current); - var instance = current.stateNode; - if ("function" === typeof instance.componentWillUnmount) - try { - (instance.props = current.memoizedProps), - (instance.state = current.memoizedState), - instance.componentWillUnmount(); - } catch (unmountError) { - captureError(current, unmountError); + var instance = finishedWork.stateNode; + if (finishedWork.effectTag & 4) + if (null === current) + (instance.props = finishedWork.memoizedProps), + (instance.state = finishedWork.memoizedState), + instance.componentDidMount(); + else { + var prevProps = current.memoizedProps; + current = current.memoizedState; + instance.props = finishedWork.memoizedProps; + instance.state = finishedWork.memoizedState; + instance.componentDidUpdate(prevProps, current); } + finishedWork = finishedWork.updateQueue; + null !== finishedWork && commitCallbacks(finishedWork, instance); + break; + case 3: + instance = finishedWork.updateQueue; + if (null !== instance) { + current = null; + if (null !== finishedWork.child) + switch (finishedWork.child.tag) { + case 5: + current = getPublicInstance(finishedWork.child.stateNode); + break; + case 2: + current = finishedWork.child.stateNode; + } + commitCallbacks(instance, current); + } break; case 5: - safelyDetachRef(current); + instance = finishedWork.stateNode; + null === current && + finishedWork.effectTag & 4 && + commitMount( + instance, + finishedWork.type, + finishedWork.memoizedProps, + finishedWork + ); break; - case 7: - commitNestedUnmounts(current.stateNode); + case 6: break; case 4: - mutation && unmountHostComponents(current); - } - } - function commitNestedUnmounts(root) { - for (var node = root; ; ) - if ( - (commitUnmount(node), - null === node.child || (mutation && 4 === node.tag)) - ) { - if (node === root) break; - for (; null === node.sibling; ) { - if (null === node["return"] || node["return"] === root) return; - node = node["return"]; - } - node.sibling["return"] = node["return"]; - node = node.sibling; - } else (node.child["return"] = node), (node = node.child); - } - function isHostParent(fiber) { - return 5 === fiber.tag || 3 === fiber.tag || 4 === fiber.tag; - } - function unmountHostComponents(current) { - for ( - var node = current, - currentParentIsValid = !1, - currentParent = void 0, - currentParentIsContainer = void 0; - ; - - ) { - if (!currentParentIsValid) { - currentParentIsValid = node["return"]; - a: for (;;) { - invariant( - null !== currentParentIsValid, - "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." - ); - switch (currentParentIsValid.tag) { - case 5: - currentParent = currentParentIsValid.stateNode; - currentParentIsContainer = !1; - break a; - case 3: - currentParent = currentParentIsValid.stateNode.containerInfo; - currentParentIsContainer = !0; - break a; - case 4: - currentParent = currentParentIsValid.stateNode.containerInfo; - currentParentIsContainer = !0; - break a; - } - currentParentIsValid = currentParentIsValid["return"]; - } - currentParentIsValid = !0; - } - if (5 === node.tag || 6 === node.tag) - commitNestedUnmounts(node), - currentParentIsContainer - ? removeChildFromContainer(currentParent, node.stateNode) - : removeChild(currentParent, node.stateNode); - else if ( - (4 === node.tag - ? (currentParent = node.stateNode.containerInfo) - : commitUnmount(node), - null !== node.child) - ) { - node.child["return"] = node; - node = node.child; - continue; - } - if (node === current) break; - for (; null === node.sibling; ) { - if (null === node["return"] || node["return"] === current) return; - node = node["return"]; - 4 === node.tag && (currentParentIsValid = !1); - } - node.sibling["return"] = node["return"]; - node = node.sibling; - } - } - var getPublicInstance = config.getPublicInstance, - mutation = config.mutation; - config = config.persistence; - mutation || - (config - ? invariant(!1, "Persistent reconciler is disabled.") - : invariant(!1, "Noop reconciler is disabled.")); - var commitMount = mutation.commitMount, - commitUpdate = mutation.commitUpdate, - resetTextContent = mutation.resetTextContent, - commitTextUpdate = mutation.commitTextUpdate, - appendChild = mutation.appendChild, - appendChildToContainer = mutation.appendChildToContainer, - insertBefore = mutation.insertBefore, - insertInContainerBefore = mutation.insertInContainerBefore, - removeChild = mutation.removeChild, - removeChildFromContainer = mutation.removeChildFromContainer; - return { - commitResetTextContent: function(current) { - resetTextContent(current.stateNode); - }, - commitPlacement: function(finishedWork) { - a: { - for (var parent = finishedWork["return"]; null !== parent; ) { - if (isHostParent(parent)) { - var parentFiber = parent; - break a; - } - parent = parent["return"]; - } + break; + default: invariant( !1, - "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." ); - parentFiber = void 0; - } - var isContainer = (parent = void 0); - switch (parentFiber.tag) { - case 5: - parent = parentFiber.stateNode; - isContainer = !1; - break; - case 3: - parent = parentFiber.stateNode.containerInfo; - isContainer = !0; - break; - case 4: - parent = parentFiber.stateNode.containerInfo; - isContainer = !0; - break; - default: - invariant( - !1, - "Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue." - ); - } - parentFiber.effectTag & 16 && - (resetTextContent(parent), (parentFiber.effectTag &= -17)); - a: b: for (parentFiber = finishedWork; ; ) { - for (; null === parentFiber.sibling; ) { - if ( - null === parentFiber["return"] || - isHostParent(parentFiber["return"]) - ) { - parentFiber = null; - break a; - } - parentFiber = parentFiber["return"]; - } - parentFiber.sibling["return"] = parentFiber["return"]; - for ( - parentFiber = parentFiber.sibling; - 5 !== parentFiber.tag && 6 !== parentFiber.tag; - - ) { - if (parentFiber.effectTag & 2) continue b; - if (null === parentFiber.child || 4 === parentFiber.tag) continue b; - else - (parentFiber.child["return"] = parentFiber), - (parentFiber = parentFiber.child); - } - if (!(parentFiber.effectTag & 2)) { - parentFiber = parentFiber.stateNode; - break a; - } - } - for (var node = finishedWork; ; ) { - if (5 === node.tag || 6 === node.tag) - parentFiber - ? isContainer - ? insertInContainerBefore(parent, node.stateNode, parentFiber) - : insertBefore(parent, node.stateNode, parentFiber) - : isContainer - ? appendChildToContainer(parent, node.stateNode) - : appendChild(parent, node.stateNode); - else if (4 !== node.tag && null !== node.child) { - node.child["return"] = node; - node = node.child; - continue; - } - if (node === finishedWork) break; - for (; null === node.sibling; ) { - if (null === node["return"] || node["return"] === finishedWork) - return; - node = node["return"]; - } - node.sibling["return"] = node["return"]; - node = node.sibling; - } - }, - commitDeletion: function(current) { - unmountHostComponents(current); - current["return"] = null; - current.child = null; - current.alternate && - ((current.alternate.child = null), - (current.alternate["return"] = null)); - }, - commitWork: function(current, finishedWork) { + } + } + function commitAttachRef(finishedWork) { + var ref = finishedWork.ref; + if (null !== ref) { + var instance = finishedWork.stateNode; switch (finishedWork.tag) { - case 2: - break; case 5: - var instance = finishedWork.stateNode; - if (null != instance) { - var newProps = finishedWork.memoizedProps; - current = null !== current ? current.memoizedProps : newProps; - var type = finishedWork.type, - updatePayload = finishedWork.updateQueue; - finishedWork.updateQueue = null; - null !== updatePayload && - commitUpdate( - instance, - updatePayload, - type, - current, - newProps, - finishedWork - ); - } - break; - case 6: - invariant( - null !== finishedWork.stateNode, - "This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue." - ); - instance = finishedWork.memoizedProps; - commitTextUpdate( - finishedWork.stateNode, - null !== current ? current.memoizedProps : instance, - instance - ); - break; - case 3: + finishedWork = getPublicInstance(instance); 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." - ); + finishedWork = instance; } - }, - commitLifeCycles: function(current, finishedWork) { - switch (finishedWork.tag) { + "function" === typeof ref + ? ref(finishedWork) + : (ref.value = finishedWork); + } + } + function commitDetachRef(current) { + current = current.ref; + null !== current && + ("function" === typeof current ? current(null) : (current.value = null)); + } + function commitNestedUnmounts(root) { + for (var node = root; ; ) { + var current = node; + "function" === typeof onCommitUnmount && onCommitUnmount(current); + switch (current.tag) { case 2: - var instance = finishedWork.stateNode; - if (finishedWork.effectTag & 4) - if (null === current) - (instance.props = finishedWork.memoizedProps), - (instance.state = finishedWork.memoizedState), - instance.componentDidMount(); - else { - var prevProps = current.memoizedProps; - current = current.memoizedState; - instance.props = finishedWork.memoizedProps; - instance.state = finishedWork.memoizedState; - instance.componentDidUpdate(prevProps, current); + safelyDetachRef(current); + var instance = current.stateNode; + if ("function" === typeof instance.componentWillUnmount) + try { + (instance.props = current.memoizedProps), + (instance.state = current.memoizedState), + instance.componentWillUnmount(); + } catch (unmountError) { + captureError(current, unmountError); } - finishedWork = finishedWork.updateQueue; - null !== finishedWork && commitCallbacks(finishedWork, instance); - break; - case 3: - instance = finishedWork.updateQueue; - if (null !== instance) { - current = null; - if (null !== finishedWork.child) - switch (finishedWork.child.tag) { - case 5: - current = getPublicInstance(finishedWork.child.stateNode); - break; - case 2: - current = finishedWork.child.stateNode; - } - commitCallbacks(instance, current); - } break; case 5: - instance = finishedWork.stateNode; - null === current && - finishedWork.effectTag & 4 && - commitMount( - instance, - finishedWork.type, - finishedWork.memoizedProps, - finishedWork - ); + safelyDetachRef(current); break; - case 6: + case 7: + commitNestedUnmounts(current.stateNode); break; case 4: - break; - default: - invariant( - !1, - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); + persistence && emptyPortalContainer(current); } - }, - commitAttachRef: function(finishedWork) { - var ref = finishedWork.ref; - if (null !== ref) { - var instance = finishedWork.stateNode; + if (null === node.child || (mutation && 4 === node.tag)) { + if (node === root) break; + for (; null === node.sibling; ) { + if (null === node["return"] || node["return"] === root) return; + node = node["return"]; + } + node.sibling["return"] = node["return"]; + node = node.sibling; + } else (node.child["return"] = node), (node = node.child); + } + } + var getPublicInstance = config.getPublicInstance, + mutation = config.mutation, + persistence = config.persistence, + emptyPortalContainer = void 0; + if (!mutation) { + var commitContainer = void 0; + if (persistence) { + var replaceContainerChildren = persistence.replaceContainerChildren, + createContainerChildSet = persistence.createContainerChildSet; + emptyPortalContainer = function(current) { + current = current.stateNode.containerInfo; + var emptyChildSet = createContainerChildSet(current); + replaceContainerChildren(current, emptyChildSet); + }; + commitContainer = function(finishedWork) { switch (finishedWork.tag) { + case 2: + break; case 5: - ref(getPublicInstance(instance)); + break; + case 6: + break; + case 3: + case 4: + finishedWork = finishedWork.stateNode; + replaceContainerChildren( + finishedWork.containerInfo, + finishedWork.pendingChildren + ); break; default: - ref(instance); + 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." + ); } - } - }, - commitDetachRef: function(current) { - current = current.ref; - null !== current && current(null); - } - }; + }; + } else commitContainer = function() {}; + return { + commitResetTextContent: function() {}, + commitPlacement: function() {}, + commitDeletion: function(current) { + commitNestedUnmounts(current); + current["return"] = null; + current.child = null; + current.alternate && + ((current.alternate.child = null), + (current.alternate["return"] = null)); + }, + commitWork: function(current, finishedWork) { + commitContainer(finishedWork); + }, + commitLifeCycles: commitLifeCycles, + commitAttachRef: commitAttachRef, + commitDetachRef: commitDetachRef + }; + } + var commitMount = mutation.commitMount; + invariant(!1, "Mutating reconciler is disabled."); } var NO_CONTEXT = {}; function ReactFiberHostContext(config) { @@ -4655,6 +4570,8 @@ function ReactFiberScheduler(config) { var context = stack[i].type.context; context.currentValue = context.defaultValue; context.changedBits = 0; + changedBitsStack[i] = null; + currentValueStack[i] = null; stack[i] = null; } index$1 = -1; @@ -5846,7 +5763,7 @@ ReactFabricRenderer.injectIntoDevTools({ findFiberByHostInstance: getInstanceFromTag, getInspectorDataForViewTag: getInspectorDataForViewTag, bundleType: 0, - version: "16.2.0", + version: "16.3.0-alpha.0", 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 48a3d1767d0164..15ee4136d11ae6 100644 --- a/Libraries/Renderer/ReactNativeRenderer-dev.js +++ b/Libraries/Renderer/ReactNativeRenderer-dev.js @@ -289,78 +289,6 @@ var rethrowCaughtError = function() { } }; -/** - * Forked from fbjs/warning: - * https://github.com/facebook/fbjs/blob/e66ba20ad5be433eb54423f2b097d829324d9de6/packages/fbjs/src/__forks__/warning.js - * - * Only change is we use console.warn instead of console.error, - * and do nothing when 'console' is not supported. - * This really simplifies the code. - * --- - * Similar to invariant but only logs a warning if the condition is not met. - * This can be used to log issues in development environments in critical - * paths. Removing the logging code for production environments will keep the - * same logic and follow the same code paths. - */ - -var lowPriorityWarning = function() {}; - -{ - var printWarning = function(format) { - for ( - var _len = arguments.length, - args = Array(_len > 1 ? _len - 1 : 0), - _key = 1; - _key < _len; - _key++ - ) { - args[_key - 1] = arguments[_key]; - } - - var argIndex = 0; - var message = - "Warning: " + - format.replace(/%s/g, function() { - return args[argIndex++]; - }); - if (typeof console !== "undefined") { - console.warn(message); - } - try { - // --- Welcome to debugging React --- - // This error was thrown as a convenience so that you can use this stack - // to find the callsite that caused this warning to fire. - throw new Error(message); - } catch (x) {} - }; - - lowPriorityWarning = function(condition, format) { - if (format === undefined) { - throw new Error( - "`warning(condition, format, ...args)` requires a warning " + - "message argument" - ); - } - if (!condition) { - for ( - var _len2 = arguments.length, - args = Array(_len2 > 2 ? _len2 - 2 : 0), - _key2 = 2; - _key2 < _len2; - _key2++ - ) { - args[_key2 - 2] = arguments[_key2]; - } - - printWarning.apply(undefined, [format].concat(args)); - } - }; -} - -var lowPriorityWarning$1 = lowPriorityWarning; - -var shouldWarnOnInjection = false; - /** * Injectable ordering of event plugins. */ @@ -546,21 +474,6 @@ function injectEventPluginOrder(injectedEventPluginOrder) { * @see {EventPluginHub.injection.injectEventPluginsByName} */ function injectEventPluginsByName(injectedNamesToPlugins) { - { - if (shouldWarnOnInjection) { - var names = Object.keys(injectedNamesToPlugins).join(", "); - lowPriorityWarning$1( - false, - "Injecting custom event plugins (%s) is deprecated " + - "and will not work in React 17+. Please update your code " + - "to not depend on React internals. The stack trace for this " + - "warning should reveal the library that is using them. " + - "See https://github.com/facebook/react/issues/11689 for a discussion.", - names - ); - } - } - var isOrderingDirty = false; for (var pluginName in injectedNamesToPlugins) { if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) { @@ -3076,7 +2989,7 @@ var ReactGlobalSharedState = Object.freeze({ // TODO: this is special because it gets imported during build. -var ReactVersion = "16.2.0"; +var ReactVersion = "16.3.0-alpha.0"; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { @@ -5755,6 +5668,76 @@ function onCommitUnmount(fiber) { } } +/** + * Forked from fbjs/warning: + * https://github.com/facebook/fbjs/blob/e66ba20ad5be433eb54423f2b097d829324d9de6/packages/fbjs/src/__forks__/warning.js + * + * Only change is we use console.warn instead of console.error, + * and do nothing when 'console' is not supported. + * This really simplifies the code. + * --- + * Similar to invariant but only logs a warning if the condition is not met. + * This can be used to log issues in development environments in critical + * paths. Removing the logging code for production environments will keep the + * same logic and follow the same code paths. + */ + +var lowPriorityWarning = function() {}; + +{ + var printWarning = function(format) { + for ( + var _len = arguments.length, + args = Array(_len > 1 ? _len - 1 : 0), + _key = 1; + _key < _len; + _key++ + ) { + args[_key - 1] = arguments[_key]; + } + + var argIndex = 0; + var message = + "Warning: " + + format.replace(/%s/g, function() { + return args[argIndex++]; + }); + if (typeof console !== "undefined") { + console.warn(message); + } + try { + // --- Welcome to debugging React --- + // This error was thrown as a convenience so that you can use this stack + // to find the callsite that caused this warning to fire. + throw new Error(message); + } catch (x) {} + }; + + lowPriorityWarning = function(condition, format) { + if (format === undefined) { + throw new Error( + "`warning(condition, format, ...args)` requires a warning " + + "message argument" + ); + } + if (!condition) { + for ( + var _len2 = arguments.length, + args = Array(_len2 > 2 ? _len2 - 2 : 0), + _key2 = 2; + _key2 < _len2; + _key2++ + ) { + args[_key2 - 2] = arguments[_key2]; + } + + printWarning.apply(undefined, [format].concat(args)); + } + }; +} + +var lowPriorityWarning$1 = lowPriorityWarning; + var ReactStrictModeWarnings = { discardPendingWarnings: function() {}, flushPendingDeprecationWarnings: function() {}, @@ -5862,7 +5845,7 @@ var ReactStrictModeWarnings = { .sort() .join(", "); - warning( + lowPriorityWarning$1( false, "componentWillMount is deprecated and will be removed in the next major version. " + "Use componentDidMount instead. As a temporary workaround, " + @@ -5887,7 +5870,7 @@ var ReactStrictModeWarnings = { .sort() .join(", "); - warning( + lowPriorityWarning$1( false, "componentWillReceiveProps is deprecated and will be removed in the next major version. " + "Use static getDerivedStateFromProps instead." + @@ -5911,7 +5894,7 @@ var ReactStrictModeWarnings = { .sort() .join(", "); - warning( + lowPriorityWarning$1( false, "componentWillUpdate is deprecated and will be removed in the next major version. " + "Use componentDidUpdate instead. As a temporary workaround, " + @@ -7184,12 +7167,15 @@ var getCurrentFiberStackAddendum$1 = ReactDebugCurrentFiber.getCurrentFiberStackAddendum; var didWarnAboutMaps = void 0; +var didWarnAboutStringRefInStrictMode = void 0; var ownerHasKeyUseWarning = void 0; var ownerHasFunctionTypeWarning = void 0; var warnForMissingKey = function(child) {}; { didWarnAboutMaps = false; + didWarnAboutStringRefInStrictMode = {}; + /** * Warn if there's no key explicitly set on dynamic arrays of children or * object keys are not valid. This allows us to keep track of children between @@ -7234,9 +7220,33 @@ var warnForMissingKey = function(child) {}; var isArray$1 = Array.isArray; -function coerceRef(current, element) { +function coerceRef(returnFiber, current, element) { var mixedRef = element.ref; - if (mixedRef !== null && typeof mixedRef !== "function") { + if ( + mixedRef !== null && + typeof mixedRef !== "function" && + typeof mixedRef !== "object" + ) { + { + if (returnFiber.mode & StrictMode) { + var componentName = getComponentName(returnFiber) || "Component"; + if (!didWarnAboutStringRefInStrictMode[componentName]) { + warning( + false, + 'A string ref, "%s", has been found within a strict mode tree. ' + + "String refs are a source of potential bugs and should be avoided. " + + "We recommend using createRef() instead." + + "\n%s" + + "\n\nLearn more about using refs safely here:" + + "\nhttps://fb.me/react-strict-mode-string-ref", + mixedRef, + getStackAddendumByWorkInProgressFiber(returnFiber) + ); + didWarnAboutStringRefInStrictMode[componentName] = true; + } + } + } + if (element._owner) { var owner = element._owner; var inst = void 0; @@ -7457,7 +7467,7 @@ function ChildReconciler(shouldTrackSideEffects) { if (current !== null && current.type === element.type) { // Move based on index var existing = useFiber(current, element.props, expirationTime); - existing.ref = coerceRef(current, element); + existing.ref = coerceRef(returnFiber, current, element); existing["return"] = returnFiber; { existing._debugSource = element._source; @@ -7471,7 +7481,7 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime ); - created.ref = coerceRef(current, element); + created.ref = coerceRef(returnFiber, current, element); created["return"] = returnFiber; return created; } @@ -7541,7 +7551,7 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime ); - _created.ref = coerceRef(null, newChild); + _created.ref = coerceRef(returnFiber, null, newChild); _created["return"] = returnFiber; return _created; } @@ -8175,7 +8185,7 @@ function ChildReconciler(shouldTrackSideEffects) { : element.props, expirationTime ); - existing.ref = coerceRef(child, element); + existing.ref = coerceRef(returnFiber, child, element); existing["return"] = returnFiber; { existing._debugSource = element._source; @@ -8207,7 +8217,7 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime ); - _created4.ref = coerceRef(currentFirstChild, element); + _created4.ref = coerceRef(returnFiber, currentFirstChild, element); _created4["return"] = returnFiber; return _created4; } @@ -8414,6 +8424,8 @@ function cloneChildFibers(current, workInProgress) { newChild.sibling = null; } +var changedBitsStack = []; +var currentValueStack = []; var stack = []; var index$1 = -1; @@ -8424,9 +8436,11 @@ var rendererSigil = void 0; } function pushProvider(providerFiber) { + var context = providerFiber.type.context; index$1 += 1; + changedBitsStack[index$1] = context.changedBits; + currentValueStack[index$1] = context.currentValue; stack[index$1] = providerFiber; - var context = providerFiber.type.context; context.currentValue = providerFiber.pendingProps.value; context.changedBits = providerFiber.stateNode; @@ -8448,17 +8462,15 @@ function popProvider(providerFiber) { "Unexpected pop." ); } + var changedBits = changedBitsStack[index$1]; + var currentValue = currentValueStack[index$1]; + changedBitsStack[index$1] = null; + currentValueStack[index$1] = null; stack[index$1] = null; index$1 -= 1; var context = providerFiber.type.context; - if (index$1 < 0) { - context.currentValue = context.defaultValue; - context.changedBits = 0; - } else { - var previousProviderFiber = stack[index$1]; - context.currentValue = previousProviderFiber.pendingProps.value; - context.changedBits = previousProviderFiber.stateNode; - } + context.currentValue = currentValue; + context.changedBits = changedBits; } function resetProviderStack() { @@ -8467,6 +8479,8 @@ function resetProviderStack() { var context = providerFiber.type.context; context.currentValue = context.defaultValue; context.changedBits = 0; + changedBitsStack[i] = null; + currentValueStack[i] = null; stack[i] = null; { context._currentRenderer = null; @@ -8589,7 +8603,10 @@ var ReactFiberBeginWork = function( function markRef(current, workInProgress) { var ref = workInProgress.ref; - if (ref !== null && (!current || current.ref !== ref)) { + if ( + (current === null && ref !== null) || + (current !== null && current.ref !== ref) + ) { // Schedule a Ref effect workInProgress.effectTag |= Ref; } @@ -10059,12 +10076,16 @@ var ReactFiberCommitWork = function(config, captureError) { function safelyDetachRef(current) { var ref = current.ref; if (ref !== null) { - { - invokeGuardedCallback$3(null, ref, null, null); - if (hasCaughtError$1()) { - var refError = clearCaughtError$1(); - captureError(current, refError); + if (typeof ref === "function") { + { + invokeGuardedCallback$3(null, ref, null, null); + if (hasCaughtError$1()) { + var refError = clearCaughtError$1(); + captureError(current, refError); + } } + } else { + ref.value = null; } } } @@ -10151,12 +10172,18 @@ var ReactFiberCommitWork = function(config, captureError) { var ref = finishedWork.ref; if (ref !== null) { var instance = finishedWork.stateNode; + var instanceToUse = void 0; switch (finishedWork.tag) { case HostComponent: - ref(getPublicInstance(instance)); + instanceToUse = getPublicInstance(instance); break; default: - ref(instance); + instanceToUse = instance; + } + if (typeof ref === "function") { + ref(instanceToUse); + } else { + ref.value = instanceToUse; } } } @@ -10164,7 +10191,11 @@ var ReactFiberCommitWork = function(config, captureError) { function commitDetachRef(current) { var currentRef = current.ref; if (currentRef !== null) { - currentRef(null); + if (typeof currentRef === "function") { + currentRef(null); + } else { + currentRef.value = null; + } } } diff --git a/Libraries/Renderer/ReactNativeRenderer-prod.js b/Libraries/Renderer/ReactNativeRenderer-prod.js index fa7403bf779369..b62e953324916f 100644 --- a/Libraries/Renderer/ReactNativeRenderer-prod.js +++ b/Libraries/Renderer/ReactNativeRenderer-prod.js @@ -2494,9 +2494,13 @@ function ReactFiberClassComponent( }; } var isArray$1 = Array.isArray; -function coerceRef(current, element) { - var mixedRef = element.ref; - if (null !== mixedRef && "function" !== typeof mixedRef) { +function coerceRef(returnFiber, current, element) { + returnFiber = element.ref; + if ( + null !== returnFiber && + "function" !== typeof returnFiber && + "object" !== typeof returnFiber + ) { if (element._owner) { element = element._owner; var inst = void 0; @@ -2509,9 +2513,9 @@ function coerceRef(current, element) { invariant( inst, "Missing owner for string ref %s. This error is likely caused by a bug in React. Please file an issue.", - mixedRef + returnFiber ); - var stringRef = "" + mixedRef; + var stringRef = "" + returnFiber; if ( null !== current && null !== current.ref && @@ -2526,16 +2530,16 @@ function coerceRef(current, element) { return current; } invariant( - "string" === typeof mixedRef, + "string" === typeof returnFiber, "Expected ref to be a function or a string." ); invariant( element._owner, "Element ref was specified as a string (%s) but no owner was set. This could happen for one of the following reasons:\n1. You may be adding a ref to a functional component\n2. You may be adding a ref to a component that was not created inside a component's render method\n3. You have multiple copies of React loaded\nSee https://fb.me/react-refs-must-have-owner for more information.", - mixedRef + returnFiber ); } - return mixedRef; + return returnFiber; } function throwOnInvalidObjectType(returnFiber, newChild) { "textarea" !== returnFiber.type && @@ -2620,7 +2624,7 @@ function ChildReconciler(shouldTrackSideEffects) { if (null !== current && current.type === element.type) return ( (expirationTime = useFiber(current, element.props, expirationTime)), - (expirationTime.ref = coerceRef(current, element)), + (expirationTime.ref = coerceRef(returnFiber, current, element)), (expirationTime["return"] = returnFiber), expirationTime ); @@ -2629,7 +2633,7 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime ); - expirationTime.ref = coerceRef(current, element); + expirationTime.ref = coerceRef(returnFiber, current, element); expirationTime["return"] = returnFiber; return expirationTime; } @@ -2689,7 +2693,7 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime )), - (expirationTime.ref = coerceRef(null, newChild)), + (expirationTime.ref = coerceRef(returnFiber, null, newChild)), (expirationTime["return"] = returnFiber), expirationTime ); @@ -3034,7 +3038,11 @@ function ChildReconciler(shouldTrackSideEffects) { : newChild.props, expirationTime ); - currentFirstChild.ref = coerceRef(isObject, newChild); + currentFirstChild.ref = coerceRef( + returnFiber, + isObject, + newChild + ); currentFirstChild["return"] = returnFiber; returnFiber = currentFirstChild; break a; @@ -3059,7 +3067,11 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime )), - (expirationTime.ref = coerceRef(currentFirstChild, newChild)), + (expirationTime.ref = coerceRef( + returnFiber, + currentFirstChild, + newChild + )), (expirationTime["return"] = returnFiber), (returnFiber = expirationTime)); } @@ -3155,27 +3167,29 @@ function ChildReconciler(shouldTrackSideEffects) { } var reconcileChildFibers = ChildReconciler(!0), mountChildFibers = ChildReconciler(!1), + changedBitsStack = [], + currentValueStack = [], stack = [], index$1 = -1; function pushProvider(providerFiber) { + var context = providerFiber.type.context; index$1 += 1; + changedBitsStack[index$1] = context.changedBits; + currentValueStack[index$1] = context.currentValue; stack[index$1] = providerFiber; - var context = providerFiber.type.context; context.currentValue = providerFiber.pendingProps.value; context.changedBits = providerFiber.stateNode; } function popProvider(providerFiber) { + var changedBits = changedBitsStack[index$1], + currentValue = currentValueStack[index$1]; + changedBitsStack[index$1] = null; + currentValueStack[index$1] = null; stack[index$1] = null; --index$1; providerFiber = providerFiber.type.context; - if (0 > index$1) - (providerFiber.currentValue = providerFiber.defaultValue), - (providerFiber.changedBits = 0); - else { - var previousProviderFiber = stack[index$1]; - providerFiber.currentValue = previousProviderFiber.pendingProps.value; - providerFiber.changedBits = previousProviderFiber.stateNode; - } + providerFiber.currentValue = currentValue; + providerFiber.changedBits = changedBits; } function ReactFiberBeginWork( config, @@ -3203,9 +3217,11 @@ function ReactFiberBeginWork( } function markRef(current, workInProgress) { var ref = workInProgress.ref; - null === ref || - (current && current.ref === ref) || - (workInProgress.effectTag |= 128); + if ( + (null === current && null !== ref) || + (null !== current && current.ref !== ref) + ) + workInProgress.effectTag |= 128; } function finishClassComponent( current, @@ -3994,11 +4010,13 @@ function ReactFiberCommitWork(config, captureError) { function safelyDetachRef(current) { var ref = current.ref; if (null !== ref) - try { - ref(null); - } catch (refError) { - captureError(current, refError); - } + if ("function" === typeof ref) + try { + ref(null); + } catch (refError) { + captureError(current, refError); + } + else ref.value = null; } function commitUnmount(current) { "function" === typeof onCommitUnmount && onCommitUnmount(current); @@ -4326,16 +4344,22 @@ function ReactFiberCommitWork(config, captureError) { var instance = finishedWork.stateNode; switch (finishedWork.tag) { case 5: - ref(getPublicInstance(instance)); + finishedWork = getPublicInstance(instance); break; default: - ref(instance); + finishedWork = instance; } + "function" === typeof ref + ? ref(finishedWork) + : (ref.value = finishedWork); } }, commitDetachRef: function(current) { current = current.ref; - null !== current && current(null); + null !== current && + ("function" === typeof current + ? current(null) + : (current.value = null)); } }; } @@ -4658,6 +4682,8 @@ function ReactFiberScheduler(config) { var context = stack[i].type.context; context.currentValue = context.defaultValue; context.changedBits = 0; + changedBitsStack[i] = null; + currentValueStack[i] = null; stack[i] = null; } index$1 = -1; @@ -5972,7 +5998,7 @@ NativeRenderer.injectIntoDevTools({ findFiberByHostInstance: getInstanceFromTag, getInspectorDataForViewTag: getInspectorDataForViewTag, bundleType: 0, - version: "16.2.0", + version: "16.3.0-alpha.0", rendererPackageName: "react-native-renderer" }); var ReactNativeRenderer$2 = Object.freeze({ default: ReactNativeRenderer }), diff --git a/Libraries/Renderer/shims/ReactFeatureFlags.js b/Libraries/Renderer/shims/ReactFeatureFlags.js index 5a2b32e747e601..44add71fc5c5e2 100644 --- a/Libraries/Renderer/shims/ReactFeatureFlags.js +++ b/Libraries/Renderer/shims/ReactFeatureFlags.js @@ -12,7 +12,7 @@ const ReactFeatureFlags = { debugRenderPhaseSideEffects: false, debugRenderPhaseSideEffectsForStrictMode: false, - warnAboutDeprecatedLifecycles: false, + warnAboutDeprecatedLifecycles: true, }; module.exports = ReactFeatureFlags; diff --git a/Libraries/Renderer/shims/ReactTypes.js b/Libraries/Renderer/shims/ReactTypes.js index 9f0dbcff867945..26ada3c5e842f5 100644 --- a/Libraries/Renderer/shims/ReactTypes.js +++ b/Libraries/Renderer/shims/ReactTypes.js @@ -97,3 +97,7 @@ export type ReactPortal = { // TODO: figure out the API for cross-renderer implementation. implementation: any, }; + +export type RefObject = {| + value: any, +|};