From 89c627488fde570f3d02fdc2f72d9af8b6703192 Mon Sep 17 00:00:00 2001
From: Dominic Gannaway <dg@domgan.com>
Date: Thu, 6 Feb 2020 12:33:09 +0000
Subject: [PATCH] Add feature flag for removing children Map support

Update flags

Update flags
---
 packages/react/src/ReactChildren.js           | 21 +++++++++++++------
 packages/shared/ReactFeatureFlags.js          |  7 +++++--
 .../forks/ReactFeatureFlags.native-fb.js      |  1 +
 .../forks/ReactFeatureFlags.native-oss.js     |  1 +
 .../forks/ReactFeatureFlags.persistent.js     |  1 +
 .../forks/ReactFeatureFlags.test-renderer.js  |  1 +
 .../ReactFeatureFlags.test-renderer.www.js    |  1 +
 .../shared/forks/ReactFeatureFlags.testing.js |  1 +
 .../shared/forks/ReactFeatureFlags.www.js     |  2 ++
 scripts/error-codes/codes.json                |  3 ++-
 10 files changed, 30 insertions(+), 9 deletions(-)

diff --git a/packages/react/src/ReactChildren.js b/packages/react/src/ReactChildren.js
index 5941e1a75150..9329d89c57c1 100644
--- a/packages/react/src/ReactChildren.js
+++ b/packages/react/src/ReactChildren.js
@@ -11,6 +11,7 @@ import {
   REACT_ELEMENT_TYPE,
   REACT_PORTAL_TYPE,
 } from 'shared/ReactSymbols';
+import {disableMapsAsChildren} from 'shared/ReactFeatureFlags';
 
 import {isValidElement, cloneAndReplaceKey} from './ReactElement';
 import ReactDebugCurrentFrame from './ReactDebugCurrentFrame';
@@ -158,14 +159,22 @@ function traverseAllChildrenImpl(
   } else {
     const iteratorFn = getIteratorFn(children);
     if (typeof iteratorFn === 'function') {
-      if (__DEV__) {
+      if (iteratorFn === children.entries) {
+        if (disableMapsAsChildren) {
+          invariant(
+            false,
+            'Maps are not valid as a React child (found: %s). Consider converting ' +
+              'children to an array of keyed ReactElements instead.',
+            children,
+          );
+        }
         // Warn about using Maps as children
-        if (iteratorFn === children.entries) {
+        if (__DEV__) {
           if (!didWarnAboutMaps) {
-            console.error(
-              'Using Maps as children is unsupported and will likely yield ' +
-                'unexpected results. Convert it to a sequence/iterable of keyed ' +
-                'ReactElements instead.',
+            console.warn(
+              'Using Maps as children is deprecated and will be removed in ' +
+                'a future major release. Consider converting children to ' +
+                'an array of keyed ReactElements instead.',
             );
           }
           didWarnAboutMaps = true;
diff --git a/packages/shared/ReactFeatureFlags.js b/packages/shared/ReactFeatureFlags.js
index 7a3b8880ac8b..469e5c5e810a 100644
--- a/packages/shared/ReactFeatureFlags.js
+++ b/packages/shared/ReactFeatureFlags.js
@@ -97,6 +97,8 @@ export const enableNativeTargetAsInstance = false;
 // This flag provides a killswitch if that proves to break existing code somehow.
 export const deferPassiveEffectCleanupDuringUnmount = false;
 
+export const isTestEnvironment = false;
+
 // --------------------------
 // Future APIs to be deprecated
 // --------------------------
@@ -115,6 +117,9 @@ export const disableCreateFactory = false;
 // Disables children for <textarea> elements
 export const disableTextareaChildren = false;
 
+// Disables Maps as ReactElement children
+export const disableMapsAsChildren = false;
+
 // Disables ReactDOM.unstable_renderSubtreeIntoContainer
 export const disableUnstableRenderSubtreeIntoContainer = false;
 // We should remove this flag once the above flag becomes enabled
@@ -122,5 +127,3 @@ export const warnUnstableRenderSubtreeIntoContainer = false;
 
 // Disables ReactDOM.unstable_createPortal
 export const disableUnstableCreatePortal = false;
-
-export const isTestEnvironment = false;
diff --git a/packages/shared/forks/ReactFeatureFlags.native-fb.js b/packages/shared/forks/ReactFeatureFlags.native-fb.js
index 22df10b42870..3d6afec5e6e9 100644
--- a/packages/shared/forks/ReactFeatureFlags.native-fb.js
+++ b/packages/shared/forks/ReactFeatureFlags.native-fb.js
@@ -47,6 +47,7 @@ export const enableTrainModelFix = true;
 export const enableTrustedTypesIntegration = false;
 export const disableCreateFactory = false;
 export const disableTextareaChildren = false;
+export const disableMapsAsChildren = false;
 export const disableUnstableRenderSubtreeIntoContainer = false;
 export const warnUnstableRenderSubtreeIntoContainer = false;
 export const disableUnstableCreatePortal = false;
diff --git a/packages/shared/forks/ReactFeatureFlags.native-oss.js b/packages/shared/forks/ReactFeatureFlags.native-oss.js
index e1b4b6b4c5d8..c97153f3ae1d 100644
--- a/packages/shared/forks/ReactFeatureFlags.native-oss.js
+++ b/packages/shared/forks/ReactFeatureFlags.native-oss.js
@@ -42,6 +42,7 @@ export const enableTrustedTypesIntegration = false;
 export const enableNativeTargetAsInstance = false;
 export const disableCreateFactory = false;
 export const disableTextareaChildren = false;
+export const disableMapsAsChildren = false;
 export const disableUnstableRenderSubtreeIntoContainer = false;
 export const warnUnstableRenderSubtreeIntoContainer = false;
 export const disableUnstableCreatePortal = false;
diff --git a/packages/shared/forks/ReactFeatureFlags.persistent.js b/packages/shared/forks/ReactFeatureFlags.persistent.js
index b454217e3d75..deeeeb12b07c 100644
--- a/packages/shared/forks/ReactFeatureFlags.persistent.js
+++ b/packages/shared/forks/ReactFeatureFlags.persistent.js
@@ -42,6 +42,7 @@ export const enableTrustedTypesIntegration = false;
 export const enableNativeTargetAsInstance = false;
 export const disableCreateFactory = false;
 export const disableTextareaChildren = false;
+export const disableMapsAsChildren = false;
 export const disableUnstableRenderSubtreeIntoContainer = false;
 export const warnUnstableRenderSubtreeIntoContainer = false;
 export const disableUnstableCreatePortal = false;
diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.js
index da4da0629803..adc9ab91061c 100644
--- a/packages/shared/forks/ReactFeatureFlags.test-renderer.js
+++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.js
@@ -42,6 +42,7 @@ export const enableTrustedTypesIntegration = false;
 export const enableNativeTargetAsInstance = false;
 export const disableCreateFactory = false;
 export const disableTextareaChildren = false;
+export const disableMapsAsChildren = false;
 export const disableUnstableRenderSubtreeIntoContainer = false;
 export const warnUnstableRenderSubtreeIntoContainer = false;
 export const disableUnstableCreatePortal = false;
diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js
index 5ca946cd5cad..ee17330bb474 100644
--- a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js
+++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js
@@ -40,6 +40,7 @@ export const enableTrustedTypesIntegration = false;
 export const enableNativeTargetAsInstance = false;
 export const disableCreateFactory = false;
 export const disableTextareaChildren = false;
+export const disableMapsAsChildren = false;
 export const disableUnstableRenderSubtreeIntoContainer = false;
 export const warnUnstableRenderSubtreeIntoContainer = false;
 export const disableUnstableCreatePortal = false;
diff --git a/packages/shared/forks/ReactFeatureFlags.testing.js b/packages/shared/forks/ReactFeatureFlags.testing.js
index 7fb99f782d83..4bcf3cc5b791 100644
--- a/packages/shared/forks/ReactFeatureFlags.testing.js
+++ b/packages/shared/forks/ReactFeatureFlags.testing.js
@@ -42,6 +42,7 @@ export const enableTrustedTypesIntegration = false;
 export const enableNativeTargetAsInstance = false;
 export const disableCreateFactory = false;
 export const disableTextareaChildren = false;
+export const disableMapsAsChildren = false;
 export const disableUnstableRenderSubtreeIntoContainer = false;
 export const warnUnstableRenderSubtreeIntoContainer = false;
 export const disableUnstableCreatePortal = false;
diff --git a/packages/shared/forks/ReactFeatureFlags.www.js b/packages/shared/forks/ReactFeatureFlags.www.js
index 9a00f62a4af6..7cc5a9ae1c71 100644
--- a/packages/shared/forks/ReactFeatureFlags.www.js
+++ b/packages/shared/forks/ReactFeatureFlags.www.js
@@ -96,6 +96,8 @@ export const disableCreateFactory = false;
 
 export const disableTextareaChildren = false;
 
+export const disableMapsAsChildren = false;
+
 export const disableUnstableRenderSubtreeIntoContainer = false;
 
 export const warnUnstableRenderSubtreeIntoContainer = false;
diff --git a/scripts/error-codes/codes.json b/scripts/error-codes/codes.json
index f0f93e9b6949..654b283dc676 100644
--- a/scripts/error-codes/codes.json
+++ b/scripts/error-codes/codes.json
@@ -344,5 +344,6 @@
   "343": "ReactDOMServer does not yet support scope components.",
   "344": "Expected prepareToHydrateHostSuspenseInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.",
   "345": "Root did not complete. This is a bug in React.",
-  "346": "An event responder context was used outside of an event cycle."
+  "346": "An event responder context was used outside of an event cycle.",
+  "347": "Maps are not valid as a React child (found: %s). Consider converting children to an array of keyed ReactElements instead."
 }
