Skip to content

Commit 7508b88

Browse files
committed
Update react-is implementation
- `react-is` has changed the `REACT_ELEMENT_TYPE` symbol from `'react.element'` to `'react.transitional.element'`. We want our changes to be non-breaking and backwards-compatible so we conditionally set the `REACT_ELEMENT_TYPE` based on the detected version of React.
1 parent 0838c62 commit 7508b88

File tree

1 file changed

+35
-55
lines changed

1 file changed

+35
-55
lines changed

src/utils/react-is.ts

Lines changed: 35 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,22 @@
11
import type { ElementType, MemoExoticComponent, ReactElement } from 'react'
2+
import React from 'react'
23

34
// Directly ported from:
4-
// https://unpkg.com/browse/react-is@18.3.0-canary-ee68446ff-20231115/cjs/react-is.production.js
5+
// https://unpkg.com/browse/react-is@19.0.0-beta-04b058868c-20240508/cjs/react-is.production.js
56
// It's very possible this could change in the future, but given that
67
// we only use these in `connect`, this is a low priority.
78

8-
const REACT_ELEMENT_TYPE = Symbol.for('react.element')
9+
export const IS_REACT_19 = React.version.startsWith('19')
10+
11+
const REACT_ELEMENT_TYPE = Symbol.for(
12+
IS_REACT_19 ? 'react.transitional.element' : 'react.element',
13+
)
914
const REACT_PORTAL_TYPE = Symbol.for('react.portal')
1015
const REACT_FRAGMENT_TYPE = Symbol.for('react.fragment')
1116
const REACT_STRICT_MODE_TYPE = Symbol.for('react.strict_mode')
1217
const REACT_PROFILER_TYPE = Symbol.for('react.profiler')
13-
const REACT_PROVIDER_TYPE = Symbol.for('react.provider')
18+
const REACT_CONSUMER_TYPE = Symbol.for('react.consumer')
1419
const REACT_CONTEXT_TYPE = Symbol.for('react.context')
15-
const REACT_SERVER_CONTEXT_TYPE = Symbol.for('react.server_context')
1620
const REACT_FORWARD_REF_TYPE = Symbol.for('react.forward_ref')
1721
const REACT_SUSPENSE_TYPE = Symbol.for('react.suspense')
1822
const REACT_SUSPENSE_LIST_TYPE = Symbol.for('react.suspense_list')
@@ -25,87 +29,63 @@ export const ForwardRef = REACT_FORWARD_REF_TYPE
2529
export const Memo = REACT_MEMO_TYPE
2630

2731
export function isValidElementType(type: any): type is ElementType {
28-
if (typeof type === 'string' || typeof type === 'function') {
29-
return true
30-
} // Note: typeof might be other than 'symbol' or 'number' (e.g. if it's a polyfill).
31-
32-
if (
32+
return typeof type === 'string' ||
33+
typeof type === 'function' ||
3334
type === REACT_FRAGMENT_TYPE ||
3435
type === REACT_PROFILER_TYPE ||
3536
type === REACT_STRICT_MODE_TYPE ||
3637
type === REACT_SUSPENSE_TYPE ||
3738
type === REACT_SUSPENSE_LIST_TYPE ||
38-
type === REACT_OFFSCREEN_TYPE
39-
) {
40-
return true
41-
}
42-
43-
if (typeof type === 'object' && type !== null) {
44-
if (
45-
type.$$typeof === REACT_LAZY_TYPE ||
46-
type.$$typeof === REACT_MEMO_TYPE ||
47-
type.$$typeof === REACT_PROVIDER_TYPE ||
48-
type.$$typeof === REACT_CONTEXT_TYPE ||
49-
type.$$typeof === REACT_FORWARD_REF_TYPE || // This needs to include all possible module reference object
50-
// types supported by any Flight configuration anywhere since
51-
// we don't know which Flight build this will end up being used
52-
// with.
53-
type.$$typeof === REACT_CLIENT_REFERENCE ||
54-
type.getModuleId !== undefined
55-
) {
56-
return true
57-
}
58-
}
59-
60-
return false
39+
type === REACT_OFFSCREEN_TYPE ||
40+
(typeof type === 'object' &&
41+
type !== null &&
42+
(type.$$typeof === REACT_LAZY_TYPE ||
43+
type.$$typeof === REACT_MEMO_TYPE ||
44+
type.$$typeof === REACT_CONTEXT_TYPE ||
45+
type.$$typeof === REACT_CONSUMER_TYPE ||
46+
type.$$typeof === REACT_FORWARD_REF_TYPE ||
47+
type.$$typeof === REACT_CLIENT_REFERENCE ||
48+
type.getModuleId !== undefined))
49+
? !0
50+
: !1
6151
}
6252

6353
function typeOf(object: any): symbol | undefined {
6454
if (typeof object === 'object' && object !== null) {
65-
const $$typeof = object.$$typeof
55+
const { $$typeof } = object
6656

6757
switch ($$typeof) {
68-
case REACT_ELEMENT_TYPE: {
69-
const type = object.type
70-
71-
switch (type) {
58+
case REACT_ELEMENT_TYPE:
59+
switch (((object = object.type), object)) {
7260
case REACT_FRAGMENT_TYPE:
7361
case REACT_PROFILER_TYPE:
7462
case REACT_STRICT_MODE_TYPE:
7563
case REACT_SUSPENSE_TYPE:
7664
case REACT_SUSPENSE_LIST_TYPE:
77-
return type
78-
79-
default: {
80-
const $$typeofType = type && type.$$typeof
81-
82-
switch ($$typeofType) {
83-
case REACT_SERVER_CONTEXT_TYPE:
65+
return object
66+
default:
67+
switch (((object = object && object.$$typeof), object)) {
8468
case REACT_CONTEXT_TYPE:
8569
case REACT_FORWARD_REF_TYPE:
8670
case REACT_LAZY_TYPE:
8771
case REACT_MEMO_TYPE:
88-
case REACT_PROVIDER_TYPE:
89-
return $$typeofType
90-
72+
return object
73+
case REACT_CONSUMER_TYPE:
74+
return object
9175
default:
9276
return $$typeof
9377
}
94-
}
9578
}
96-
}
97-
98-
case REACT_PORTAL_TYPE: {
79+
case REACT_PORTAL_TYPE:
9980
return $$typeof
100-
}
10181
}
10282
}
103-
104-
return undefined
10583
}
10684

10785
export function isContextConsumer(object: any): object is ReactElement {
108-
return typeOf(object) === REACT_CONTEXT_TYPE
86+
return IS_REACT_19
87+
? typeOf(object) === REACT_CONSUMER_TYPE
88+
: typeOf(object) === REACT_CONTEXT_TYPE
10989
}
11090

11191
export function isMemo(object: any): object is MemoExoticComponent<any> {

0 commit comments

Comments
 (0)