Temporarily feature flag numeric fallback for symbols (#24401)
Ricky committed
Apr 19, 2022 at 17:34 UTC
4175f05934d3954827c00b7633c1ce8e4e87d227
15 files changed
+328
-27
packages/react/src/__tests__/ReactElement-test.js
+112
@@ -9,16 +9,26 @@
9
10
'use strict';
11
12
+import {enableSymbolFallbackForWWW} from 'shared/ReactFeatureFlags';
13
+
14
let React;
15
let ReactDOM;
16
let ReactTestUtils;
17
18
describe('ReactElement', () => {
19
let ComponentClass;
20
+ let originalSymbol;
21
22
beforeEach(() => {
23
jest.resetModules();
24
25
+ if (enableSymbolFallbackForWWW) {
26
+ // Delete the native Symbol if we have one to ensure we test the
27
+ // unpolyfilled environment.
28
+ originalSymbol = global.Symbol;
29
+ global.Symbol = undefined;
30
+ }
31
+
32
React = require('react');
33
ReactDOM = require('react-dom');
34
ReactTestUtils = require('react-dom/test-utils');
@@ -31,6 +41,17 @@ describe('ReactElement', () => {
41
};
42
});
43
44
+ afterEach(() => {
45
+ if (enableSymbolFallbackForWWW) {
46
+ global.Symbol = originalSymbol;
47
+ }
48
+ });
49
+
50
+ // @gate enableSymbolFallbackForWWW
51
+ it('uses the fallback value when in an environment without Symbol', () => {
52
+ expect((<div />).$$typeof).toBe(0xeac7);
53
+ });
54
+
55
it('returns a complete element according to spec', () => {
56
const element = React.createElement(ComponentClass);
57
expect(element.type).toBe(ComponentClass);
@@ -280,6 +301,42 @@ describe('ReactElement', () => {
301
expect(element.type.someStaticMethod()).toBe('someReturnValue');
302
});
303
304
+ // NOTE: We're explicitly not using JSX here. This is intended to test
305
+ // classic JS without JSX.
306
+ // @gate enableSymbolFallbackForWWW
307
+ it('identifies valid elements', () => {
308
+ class Component extends React.Component {
309
+ render() {
310
+ return React.createElement('div');
311
+ }
312
+ }
313
+
314
+ expect(React.isValidElement(React.createElement('div'))).toEqual(true);
315
+ expect(React.isValidElement(React.createElement(Component))).toEqual(true);
316
+
317
+ expect(React.isValidElement(null)).toEqual(false);
318
+ expect(React.isValidElement(true)).toEqual(false);
319
+ expect(React.isValidElement({})).toEqual(false);
320
+ expect(React.isValidElement('string')).toEqual(false);
321
+ if (!__EXPERIMENTAL__) {
322
+ let factory;
323
+ expect(() => {
324
+ factory = React.createFactory('div');
325
+ }).toWarnDev(
326
+ 'Warning: React.createFactory() is deprecated and will be removed in a ' +
327
+ 'future major release. Consider using JSX or use React.createElement() ' +
328
+ 'directly instead.',
329
+ {withoutStack: true},
330
+ );
331
+ expect(React.isValidElement(factory)).toEqual(false);
332
+ }
333
+ expect(React.isValidElement(Component)).toEqual(false);
334
+ expect(React.isValidElement({type: 'div', props: {}})).toEqual(false);
335
+
336
+ const jsonElement = JSON.stringify(React.createElement('div'));
337
+ expect(React.isValidElement(JSON.parse(jsonElement))).toBe(true);
338
+ });
339
+
340
// NOTE: We're explicitly not using JSX here. This is intended to test
341
// classic JS without JSX.
342
it('is indistinguishable from a plain object', () => {
@@ -397,6 +454,7 @@ describe('ReactElement', () => {
454
455
// NOTE: We're explicitly not using JSX here. This is intended to test
456
// classic JS without JSX.
457
+ // @gate !enableSymbolFallbackForWWW
458
it('identifies elements, but not JSON, if Symbols are supported', () => {
459
class Component extends React.Component {
460
render() {
@@ -429,4 +487,58 @@ describe('ReactElement', () => {
487
const jsonElement = JSON.stringify(React.createElement('div'));
488
expect(React.isValidElement(JSON.parse(jsonElement))).toBe(false);
489
});
490
+
491
+ // NOTE: We're explicitly not using JSX here. This is intended to test
492
+ // classic JS without JSX.
493
+ it('identifies elements, but not JSON, if Symbols are supported (with polyfill)', () => {
494
+ // Rudimentary polyfill
495
+ // Once all jest engines support Symbols natively we can swap this to test
496
+ // WITH native Symbols by default.
497
+ const REACT_ELEMENT_TYPE = function() {}; // fake Symbol
498
+ const OTHER_SYMBOL = function() {}; // another fake Symbol
499
+ global.Symbol = function(name) {
500
+ return OTHER_SYMBOL;
501
+ };
502
+ global.Symbol.for = function(key) {
503
+ if (key === 'react.element') {
504
+ return REACT_ELEMENT_TYPE;
505
+ }
506
+ return OTHER_SYMBOL;
507
+ };
508
+
509
+ jest.resetModules();
510
+
511
+ React = require('react');
512
+
513
+ class Component extends React.Component {
514
+ render() {
515
+ return React.createElement('div');
516
+ }
517
+ }
518
+
519
+ expect(React.isValidElement(React.createElement('div'))).toEqual(true);
520
+ expect(React.isValidElement(React.createElement(Component))).toEqual(true);
521
+
522
+ expect(React.isValidElement(null)).toEqual(false);
523
+ expect(React.isValidElement(true)).toEqual(false);
524
+ expect(React.isValidElement({})).toEqual(false);
525
+ expect(React.isValidElement('string')).toEqual(false);
526
+ if (!__EXPERIMENTAL__) {
527
+ let factory;
528
+ expect(() => {
529
+ factory = React.createFactory('div');
530
+ }).toWarnDev(
531
+ 'Warning: React.createFactory() is deprecated and will be removed in a ' +
532
+ 'future major release. Consider using JSX or use React.createElement() ' +
533
+ 'directly instead.',
534
+ {withoutStack: true},
535
+ );
536
+ expect(React.isValidElement(factory)).toEqual(false);
537
+ }
538
+ expect(React.isValidElement(Component)).toEqual(false);
539
+ expect(React.isValidElement({type: 'div', props: {}})).toEqual(false);
540
+
541
+ const jsonElement = JSON.stringify(React.createElement('div'));
542
+ expect(React.isValidElement(JSON.parse(jsonElement))).toBe(false);
543
+ });
544
});
packages/react/src/__tests__/ReactElementJSX-test.js
+113
@@ -9,6 +9,8 @@
9
10
'use strict';
11
12
+import {enableSymbolFallbackForWWW} from 'shared/ReactFeatureFlags';
13
+
14
let React;
15
let ReactDOM;
16
let ReactTestUtils;
@@ -20,9 +22,18 @@ let JSXDEVRuntime;
22
// A lot of these tests are pulled from ReactElement-test because
23
// this api is meant to be backwards compatible.
24
describe('ReactElement.jsx', () => {
25
+ let originalSymbol;
26
+
27
beforeEach(() => {
28
jest.resetModules();
29
30
+ if (enableSymbolFallbackForWWW) {
31
+ // Delete the native Symbol if we have one to ensure we test the
32
+ // unpolyfilled environment.
33
+ originalSymbol = global.Symbol;
34
+ global.Symbol = undefined;
35
+ }
36
+
37
React = require('react');
38
JSXRuntime = require('react/jsx-runtime');
39
JSXDEVRuntime = require('react/jsx-dev-runtime');
@@ -30,6 +41,12 @@ describe('ReactElement.jsx', () => {
41
ReactTestUtils = require('react-dom/test-utils');
42
});
43
44
+ afterEach(() => {
45
+ if (enableSymbolFallbackForWWW) {
46
+ global.Symbol = originalSymbol;
47
+ }
48
+ });
49
+
50
it('allows static methods to be called using the type property', () => {
51
class StaticMethodComponentClass extends React.Component {
52
render() {
@@ -42,6 +59,48 @@ describe('ReactElement.jsx', () => {
59
expect(element.type.someStaticMethod()).toBe('someReturnValue');
60
});
61
62
+ // @gate enableSymbolFallbackForWWW
63
+ it('identifies valid elements', () => {
64
+ class Component extends React.Component {
65
+ render() {
66
+ return JSXRuntime.jsx('div', {});
67
+ }
68
+ }
69
+
70
+ expect(React.isValidElement(JSXRuntime.jsx('div', {}))).toEqual(true);
71
+ expect(React.isValidElement(JSXRuntime.jsx(Component, {}))).toEqual(true);
72
+ expect(
73
+ React.isValidElement(JSXRuntime.jsx(JSXRuntime.Fragment, {})),
74
+ ).toEqual(true);
75
+ if (__DEV__) {
76
+ expect(React.isValidElement(JSXDEVRuntime.jsxDEV('div', {}))).toEqual(
77
+ true,
78
+ );
79
+ }
80
+
81
+ expect(React.isValidElement(null)).toEqual(false);
82
+ expect(React.isValidElement(true)).toEqual(false);
83
+ expect(React.isValidElement({})).toEqual(false);
84
+ expect(React.isValidElement('string')).toEqual(false);
85
+ if (!__EXPERIMENTAL__) {
86
+ let factory;
87
+ expect(() => {
88
+ factory = React.createFactory('div');
89
+ }).toWarnDev(
90
+ 'Warning: React.createFactory() is deprecated and will be removed in a ' +
91
+ 'future major release. Consider using JSX or use React.createElement() ' +
92
+ 'directly instead.',
93
+ {withoutStack: true},
94
+ );
95
+ expect(React.isValidElement(factory)).toEqual(false);
96
+ }
97
+ expect(React.isValidElement(Component)).toEqual(false);
98
+ expect(React.isValidElement({type: 'div', props: {}})).toEqual(false);
99
+
100
+ const jsonElement = JSON.stringify(JSXRuntime.jsx('div', {}));
101
+ expect(React.isValidElement(JSON.parse(jsonElement))).toBe(true);
102
+ });
103
+
104
it('is indistinguishable from a plain object', () => {
105
const element = JSXRuntime.jsx('div', {className: 'foo'});
106
const object = {};
@@ -235,6 +294,7 @@ describe('ReactElement.jsx', () => {
294
);
295
});
296
297
+ // @gate !enableSymbolFallbackForWWW
298
it('identifies elements, but not JSON, if Symbols are supported', () => {
299
class Component extends React.Component {
300
render() {
@@ -276,6 +336,59 @@ describe('ReactElement.jsx', () => {
336
expect(React.isValidElement(JSON.parse(jsonElement))).toBe(false);
337
});
338
339
+ it('identifies elements, but not JSON, if Symbols are polyfilled', () => {
340
+ // Rudimentary polyfill
341
+ // Once all jest engines support Symbols natively we can swap this to test
342
+ // WITH native Symbols by default.
343
+ const REACT_ELEMENT_TYPE = function() {}; // fake Symbol
344
+ const OTHER_SYMBOL = function() {}; // another fake Symbol
345
+ global.Symbol = function(name) {
346
+ return OTHER_SYMBOL;
347
+ };
348
+ global.Symbol.for = function(key) {
349
+ if (key === 'react.element') {
350
+ return REACT_ELEMENT_TYPE;
351
+ }
352
+ return OTHER_SYMBOL;
353
+ };
354
+
355
+ jest.resetModules();
356
+
357
+ React = require('react');
358
+ JSXRuntime = require('react/jsx-runtime');
359
+
360
+ class Component extends React.Component {
361
+ render() {
362
+ return JSXRuntime.jsx('div');
363
+ }
364
+ }
365
+
366
+ expect(React.isValidElement(JSXRuntime.jsx('div', {}))).toEqual(true);
367
+ expect(React.isValidElement(JSXRuntime.jsx(Component, {}))).toEqual(true);
368
+
369
+ expect(React.isValidElement(null)).toEqual(false);
370
+ expect(React.isValidElement(true)).toEqual(false);
371
+ expect(React.isValidElement({})).toEqual(false);
372
+ expect(React.isValidElement('string')).toEqual(false);
373
+ if (!__EXPERIMENTAL__) {
374
+ let factory;
375
+ expect(() => {
376
+ factory = React.createFactory('div');
377
+ }).toWarnDev(
378
+ 'Warning: React.createFactory() is deprecated and will be removed in a ' +
379
+ 'future major release. Consider using JSX or use React.createElement() ' +
380
+ 'directly instead.',
381
+ {withoutStack: true},
382
+ );
383
+ expect(React.isValidElement(factory)).toEqual(false);
384
+ }
385
+ expect(React.isValidElement(Component)).toEqual(false);
386
+ expect(React.isValidElement({type: 'div', props: {}})).toEqual(false);
387
+
388
+ const jsonElement = JSON.stringify(JSXRuntime.jsx('div', {}));
389
+ expect(React.isValidElement(JSON.parse(jsonElement))).toBe(false);
390
+ });
391
+
392
it('should warn when unkeyed children are passed to jsx', () => {
393
const container = document.createElement('div');
394
packages/shared/ReactFeatureFlags.js
+3
@@ -28,6 +28,9 @@ export const enablePersistentOffscreenHostContainer = false;
28
// like migrating internal callers or performance testing.
29
// -----------------------------------------------------------------------------
30
31
+// This is blocked on adding a symbol polyfill to www.
32
+export const enableSymbolFallbackForWWW = false;
33
+
34
// This rolled out to 10% public in www, so we should be able to land, but some
35
// internal tests need to be updated. The open source behavior is correct.
36
export const skipUnmountedBoundaries = true;
packages/shared/ReactSymbols.js
+64
-25
@@ -11,33 +11,72 @@
11
// When adding new symbols to this file,
12
// Please consider also adding to 'react-devtools-shared/src/backend/ReactSymbols'
13
14
+import {enableSymbolFallbackForWWW} from './ReactFeatureFlags';
15
+
16
+const usePolyfill =
17
+ enableSymbolFallbackForWWW && (typeof Symbol !== 'function' || !Symbol.for);
18
+
19
// The Symbol used to tag the ReactElement-like types.
15
-export const REACT_ELEMENT_TYPE = Symbol.for('react.element');
16
-export const REACT_PORTAL_TYPE = Symbol.for('react.portal');
17
-export const REACT_FRAGMENT_TYPE = Symbol.for('react.fragment');
18
-export const REACT_STRICT_MODE_TYPE = Symbol.for('react.strict_mode');
19
-export const REACT_PROFILER_TYPE = Symbol.for('react.profiler');
20
-export const REACT_PROVIDER_TYPE = Symbol.for('react.provider');
21
-export const REACT_CONTEXT_TYPE = Symbol.for('react.context');
22
-export const REACT_SERVER_CONTEXT_TYPE = Symbol.for('react.server_context');
23
-export const REACT_FORWARD_REF_TYPE = Symbol.for('react.forward_ref');
24
-export const REACT_SUSPENSE_TYPE = Symbol.for('react.suspense');
25
-export const REACT_SUSPENSE_LIST_TYPE = Symbol.for('react.suspense_list');
26
-export const REACT_MEMO_TYPE = Symbol.for('react.memo');
27
-export const REACT_LAZY_TYPE = Symbol.for('react.lazy');
28
-export const REACT_SCOPE_TYPE = Symbol.for('react.scope');
29
-export const REACT_DEBUG_TRACING_MODE_TYPE = Symbol.for(
30
- 'react.debug_trace_mode',
31
-);
32
-export const REACT_OFFSCREEN_TYPE = Symbol.for('react.offscreen');
33
-export const REACT_LEGACY_HIDDEN_TYPE = Symbol.for('react.legacy_hidden');
34
-export const REACT_CACHE_TYPE = Symbol.for('react.cache');
35
-export const REACT_TRACING_MARKER_TYPE = Symbol.for('react.tracing_marker');
36
-export const REACT_SERVER_CONTEXT_DEFAULT_VALUE_NOT_LOADED = Symbol.for(
37
- 'react.default_value',
38
-);
20
+export const REACT_ELEMENT_TYPE = usePolyfill
21
+ ? 0xeac7
22
+ : Symbol.for('react.element');
23
+export const REACT_PORTAL_TYPE = usePolyfill
24
+ ? 0xeaca
25
+ : Symbol.for('react.portal');
26
+export const REACT_FRAGMENT_TYPE = usePolyfill
27
+ ? 0xeacb
28
+ : Symbol.for('react.fragment');
29
+export const REACT_STRICT_MODE_TYPE = usePolyfill
30
+ ? 0xeacc
31
+ : Symbol.for('react.strict_mode');
32
+export const REACT_PROFILER_TYPE = usePolyfill
33
+ ? 0xead2
34
+ : Symbol.for('react.profiler');
35
+export const REACT_PROVIDER_TYPE = usePolyfill
36
+ ? 0xeacd
37
+ : Symbol.for('react.provider');
38
+export const REACT_CONTEXT_TYPE = usePolyfill
39
+ ? 0xeace
40
+ : Symbol.for('react.context');
41
+export const REACT_SERVER_CONTEXT_TYPE = usePolyfill
42
+ ? 0xeae6
43
+ : Symbol.for('react.server_context');
44
+export const REACT_FORWARD_REF_TYPE = usePolyfill
45
+ ? 0xead0
46
+ : Symbol.for('react.forward_ref');
47
+export const REACT_SUSPENSE_TYPE = usePolyfill
48
+ ? 0xead1
49
+ : Symbol.for('react.suspense');
50
+export const REACT_SUSPENSE_LIST_TYPE = usePolyfill
51
+ ? 0xead8
52
+ : Symbol.for('react.suspense_list');
53
+export const REACT_MEMO_TYPE = usePolyfill ? 0xead3 : Symbol.for('react.memo');
54
+export const REACT_LAZY_TYPE = usePolyfill ? 0xead4 : Symbol.for('react.lazy');
55
+export const REACT_SCOPE_TYPE = usePolyfill
56
+ ? 0xead7
57
+ : Symbol.for('react.scope');
58
+export const REACT_DEBUG_TRACING_MODE_TYPE = usePolyfill
59
+ ? 0xeae1
60
+ : Symbol.for('react.debug_trace_mode');
61
+export const REACT_OFFSCREEN_TYPE = usePolyfill
62
+ ? 0xeae2
63
+ : Symbol.for('react.offscreen');
64
+export const REACT_LEGACY_HIDDEN_TYPE = usePolyfill
65
+ ? 0xeae3
66
+ : Symbol.for('react.legacy_hidden');
67
+export const REACT_CACHE_TYPE = usePolyfill
68
+ ? 0xeae4
69
+ : Symbol.for('react.cache');
70
+export const REACT_TRACING_MARKER_TYPE = usePolyfill
71
+ ? 0xeae5
72
+ : Symbol.for('react.tracing_marker');
73
+export const REACT_SERVER_CONTEXT_DEFAULT_VALUE_NOT_LOADED = usePolyfill
74
+ ? 0xeae7
75
+ : Symbol.for('react.default_value');
76
+const MAYBE_ITERATOR_SYMBOL = usePolyfill
77
+ ? typeof Symbol === 'function' && Symbol.iterator
78
+ : Symbol.iterator;
79
40
-const MAYBE_ITERATOR_SYMBOL = Symbol.iterator;
80
const FAUX_ITERATOR_SYMBOL = '@@iterator';
81
82
export function getIteratorFn(maybeIterable: ?any): ?() => ?Iterator<*> {
packages/shared/__tests__/ReactSymbols-test.internal.js
+16
@@ -26,4 +26,20 @@ describe('ReactSymbols', () => {
26
it('Symbol values should be unique', () => {
27
expectToBeUnique(Object.entries(require('shared/ReactSymbols')));
28
});
29
+
30
+ // @gate enableSymbolFallbackForWWW
31
+ it('numeric values should be unique', () => {
32
+ const originalSymbolFor = global.Symbol.for;
33
+ global.Symbol.for = null;
34
+ try {
35
+ const entries = Object.entries(require('shared/ReactSymbols')).filter(
36
+ // REACT_ASYNC_MODE_TYPE and REACT_CONCURRENT_MODE_TYPE have the same numeric value
37
+ // for legacy backwards compatibility
38
+ ([key]) => key !== 'REACT_ASYNC_MODE_TYPE',
39
+ );
40
+ expectToBeUnique(entries);
41
+ } finally {
42
+ global.Symbol.for = originalSymbolFor;
43
+ }
44
+ });
45
});
packages/shared/forks/ReactFeatureFlags.native-fb.js
+1
@@ -83,6 +83,7 @@ export const enableServerContext = false;
83
export const enableUseMutableSource = true;
84
85
export const enableTransitionTracing = false;
86
+export const enableSymbolFallbackForWWW = false;
87
88
// Flow magic to verify the exports of this file match the original version.
89
// eslint-disable-next-line no-unused-vars
packages/shared/forks/ReactFeatureFlags.native-oss.js
+1
@@ -74,6 +74,7 @@ export const enableServerContext = false;
74
export const enableUseMutableSource = false;
75
76
export const enableTransitionTracing = false;
77
+export const enableSymbolFallbackForWWW = false;
78
79
// Flow magic to verify the exports of this file match the original version.
80
// eslint-disable-next-line no-unused-vars
packages/shared/forks/ReactFeatureFlags.test-renderer.js
+1
@@ -74,6 +74,7 @@ export const enableServerContext = false;
74
export const enableUseMutableSource = false;
75
76
export const enableTransitionTracing = false;
77
+export const enableSymbolFallbackForWWW = false;
78
79
// Flow magic to verify the exports of this file match the original version.
80
// eslint-disable-next-line no-unused-vars
packages/shared/forks/ReactFeatureFlags.test-renderer.native.js
+1
@@ -72,6 +72,7 @@ export const enableServerContext = false;
72
export const enableUseMutableSource = false;
73
74
export const enableTransitionTracing = false;
75
+export const enableSymbolFallbackForWWW = false;
76
77
// Flow magic to verify the exports of this file match the original version.
78
// eslint-disable-next-line no-unused-vars
packages/shared/forks/ReactFeatureFlags.test-renderer.www.js
+1
@@ -76,6 +76,7 @@ export const enableServerContext = false;
76
export const enableUseMutableSource = true;
77
78
export const enableTransitionTracing = false;
79
+export const enableSymbolFallbackForWWW = false;
80
81
// Flow magic to verify the exports of this file match the original version.
82
// eslint-disable-next-line no-unused-vars
packages/shared/forks/ReactFeatureFlags.testing.js
+1
@@ -74,6 +74,7 @@ export const enableServerContext = false;
74
export const enableUseMutableSource = false;
75
76
export const enableTransitionTracing = false;
77
+export const enableSymbolFallbackForWWW = false;
78
79
// Flow magic to verify the exports of this file match the original version.
80
// eslint-disable-next-line no-unused-vars
packages/shared/forks/ReactFeatureFlags.testing.www.js
+1
@@ -75,6 +75,7 @@ export const enableServerContext = false;
75
export const enableUseMutableSource = true;
76
77
export const enableTransitionTracing = false;
78
+export const enableSymbolFallbackForWWW = false;
79
80
// Flow magic to verify the exports of this file match the original version.
81
// eslint-disable-next-line no-unused-vars
packages/shared/forks/ReactFeatureFlags.www-dynamic.js
+1
-1
@@ -29,7 +29,7 @@ export const enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay = __
29
export const enableClientRenderFallbackOnHydrationMismatch = __VARIANT__;
30
export const enableClientRenderFallbackOnTextMismatch = __VARIANT__;
31
export const enableTransitionTracing = __VARIANT__;
32
-
32
+export const enableSymbolFallbackForWWW = __VARIANT__;
33
// Enable this flag to help with concurrent mode debugging.
34
// It logs information to the console about React scheduling, rendering, and commit phases.
35
//
packages/shared/forks/ReactFeatureFlags.www.js
+1
@@ -115,6 +115,7 @@ export const enableCustomElementPropertySupport = __EXPERIMENTAL__;
115
116
export const enableTransitionTracing = false;
117
118
+export const enableSymbolFallbackForWWW = true;
119
// Flow magic to verify the exports of this file match the original version.
120
// eslint-disable-next-line no-unused-vars
121
type Check<_X, Y: _X, X: Y = _X> = null;
packages/shared/isValidElementType.js
+11
-1
@@ -31,9 +31,19 @@ import {
31
enableTransitionTracing,
32
enableDebugTracing,
33
enableLegacyHidden,
34
+ enableSymbolFallbackForWWW,
35
} from './ReactFeatureFlags';
36
36
-const REACT_MODULE_REFERENCE: Symbol = Symbol.for('react.module.reference');
37
+let REACT_MODULE_REFERENCE;
38
+if (enableSymbolFallbackForWWW) {
39
+ if (typeof Symbol === 'function') {
40
+ REACT_MODULE_REFERENCE = Symbol.for('react.module.reference');
41
+ } else {
42
+ REACT_MODULE_REFERENCE = 0;
43
+ }
44
+} else {
45
+ REACT_MODULE_REFERENCE = Symbol.for('react.module.reference');
46
+}
47
48
export default function isValidElementType(type: mixed) {
49
if (typeof type === 'string' || typeof type === 'function') {