From 5e80d95e034259af8c41b50756a623756cc81a77 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?H=C3=A9ctor=20Ramos?= <hramos@fb.com>
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,
+|};