Add feature flag for removing children Map support (#17990)
Dominic Gannaway committed
Feb 6, 2020 at 13:19 UTC
256d78d11f1c7da749914a8b2d35b2974a54b0f2
10 files changed
+30
-9
packages/react/src/ReactChildren.js
+15
-6
@@ -11,6 +11,7 @@ import {
11
REACT_ELEMENT_TYPE,
12
REACT_PORTAL_TYPE,
13
} from 'shared/ReactSymbols';
14
+import {disableMapsAsChildren} from 'shared/ReactFeatureFlags';
15
16
import {isValidElement, cloneAndReplaceKey} from './ReactElement';
17
import ReactDebugCurrentFrame from './ReactDebugCurrentFrame';
@@ -158,14 +159,22 @@ function traverseAllChildrenImpl(
159
} else {
160
const iteratorFn = getIteratorFn(children);
161
if (typeof iteratorFn === 'function') {
161
- if (__DEV__) {
162
+ if (iteratorFn === children.entries) {
163
+ if (disableMapsAsChildren) {
164
+ invariant(
165
+ false,
166
+ 'Maps are not valid as a React child (found: %s). Consider converting ' +
167
+ 'children to an array of keyed ReactElements instead.',
168
+ children,
169
+ );
170
+ }
171
// Warn about using Maps as children
163
- if (iteratorFn === children.entries) {
172
+ if (__DEV__) {
173
if (!didWarnAboutMaps) {
165
- console.error(
166
- 'Using Maps as children is unsupported and will likely yield ' +
167
- 'unexpected results. Convert it to a sequence/iterable of keyed ' +
168
- 'ReactElements instead.',
174
+ console.warn(
175
+ 'Using Maps as children is deprecated and will be removed in ' +
176
+ 'a future major release. Consider converting children to ' +
177
+ 'an array of keyed ReactElements instead.',
178
);
179
}
180
didWarnAboutMaps = true;
packages/shared/ReactFeatureFlags.js
+5
-2
@@ -97,6 +97,8 @@ export const enableNativeTargetAsInstance = false;
97
// This flag provides a killswitch if that proves to break existing code somehow.
98
export const deferPassiveEffectCleanupDuringUnmount = false;
99
100
+export const isTestEnvironment = false;
101
+
102
// --------------------------
103
// Future APIs to be deprecated
104
// --------------------------
@@ -115,6 +117,9 @@ export const disableCreateFactory = false;
117
// Disables children for <textarea> elements
118
export const disableTextareaChildren = false;
119
120
+// Disables Maps as ReactElement children
121
+export const disableMapsAsChildren = false;
122
+
123
// Disables ReactDOM.unstable_renderSubtreeIntoContainer
124
export const disableUnstableRenderSubtreeIntoContainer = false;
125
// We should remove this flag once the above flag becomes enabled
@@ -122,5 +127,3 @@ export const warnUnstableRenderSubtreeIntoContainer = false;
127
128
// Disables ReactDOM.unstable_createPortal
129
export const disableUnstableCreatePortal = false;
125
-
126
-export const isTestEnvironment = false;
packages/shared/forks/ReactFeatureFlags.native-fb.js
+1
@@ -47,6 +47,7 @@ export const enableTrainModelFix = true;
47
export const enableTrustedTypesIntegration = false;
48
export const disableCreateFactory = false;
49
export const disableTextareaChildren = false;
50
+export const disableMapsAsChildren = false;
51
export const disableUnstableRenderSubtreeIntoContainer = false;
52
export const warnUnstableRenderSubtreeIntoContainer = false;
53
export const disableUnstableCreatePortal = false;
packages/shared/forks/ReactFeatureFlags.native-oss.js
+1
@@ -42,6 +42,7 @@ export const enableTrustedTypesIntegration = false;
42
export const enableNativeTargetAsInstance = false;
43
export const disableCreateFactory = false;
44
export const disableTextareaChildren = false;
45
+export const disableMapsAsChildren = false;
46
export const disableUnstableRenderSubtreeIntoContainer = false;
47
export const warnUnstableRenderSubtreeIntoContainer = false;
48
export const disableUnstableCreatePortal = false;
packages/shared/forks/ReactFeatureFlags.persistent.js
+1
@@ -42,6 +42,7 @@ export const enableTrustedTypesIntegration = false;
42
export const enableNativeTargetAsInstance = false;
43
export const disableCreateFactory = false;
44
export const disableTextareaChildren = false;
45
+export const disableMapsAsChildren = false;
46
export const disableUnstableRenderSubtreeIntoContainer = false;
47
export const warnUnstableRenderSubtreeIntoContainer = false;
48
export const disableUnstableCreatePortal = false;
packages/shared/forks/ReactFeatureFlags.test-renderer.js
+1
@@ -42,6 +42,7 @@ export const enableTrustedTypesIntegration = false;
42
export const enableNativeTargetAsInstance = false;
43
export const disableCreateFactory = false;
44
export const disableTextareaChildren = false;
45
+export const disableMapsAsChildren = false;
46
export const disableUnstableRenderSubtreeIntoContainer = false;
47
export const warnUnstableRenderSubtreeIntoContainer = false;
48
export const disableUnstableCreatePortal = false;
packages/shared/forks/ReactFeatureFlags.test-renderer.www.js
+1
@@ -40,6 +40,7 @@ export const enableTrustedTypesIntegration = false;
40
export const enableNativeTargetAsInstance = false;
41
export const disableCreateFactory = false;
42
export const disableTextareaChildren = false;
43
+export const disableMapsAsChildren = false;
44
export const disableUnstableRenderSubtreeIntoContainer = false;
45
export const warnUnstableRenderSubtreeIntoContainer = false;
46
export const disableUnstableCreatePortal = false;
packages/shared/forks/ReactFeatureFlags.testing.js
+1
@@ -42,6 +42,7 @@ export const enableTrustedTypesIntegration = false;
42
export const enableNativeTargetAsInstance = false;
43
export const disableCreateFactory = false;
44
export const disableTextareaChildren = false;
45
+export const disableMapsAsChildren = false;
46
export const disableUnstableRenderSubtreeIntoContainer = false;
47
export const warnUnstableRenderSubtreeIntoContainer = false;
48
export const disableUnstableCreatePortal = false;
packages/shared/forks/ReactFeatureFlags.www.js
+2
@@ -96,6 +96,8 @@ export const disableCreateFactory = false;
96
97
export const disableTextareaChildren = false;
98
99
+export const disableMapsAsChildren = false;
100
+
101
export const disableUnstableRenderSubtreeIntoContainer = false;
102
103
export const warnUnstableRenderSubtreeIntoContainer = false;
scripts/error-codes/codes.json
+2
-1
@@ -344,5 +344,6 @@
344
"343": "ReactDOMServer does not yet support scope components.",
345
"344": "Expected prepareToHydrateHostSuspenseInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.",
346
"345": "Root did not complete. This is a bug in React.",
347
- "346": "An event responder context was used outside of an event cycle."
347
+ "346": "An event responder context was used outside of an event cycle.",
348
+ "347": "Maps are not valid as a React child (found: %s). Consider converting children to an array of keyed ReactElements instead."
349
}