Add support for Suspense & lazy() to the react-is package (#14423)
* Add support for lazy & Suspense to react-is
Pleun Vanderbauwhede committed
Dec 12, 2018 at 19:56 UTC
a22880e5e59d5cb17fffe04af093ea54e356538d
2 files changed
+38
-6
packages/react-is/src/ReactIs.js
+16
-4
@@ -16,11 +16,13 @@ import {
16
REACT_ELEMENT_TYPE,
17
REACT_FORWARD_REF_TYPE,
18
REACT_FRAGMENT_TYPE,
19
+ REACT_LAZY_TYPE,
20
REACT_MEMO_TYPE,
21
REACT_PORTAL_TYPE,
22
REACT_PROFILER_TYPE,
23
REACT_PROVIDER_TYPE,
24
REACT_STRICT_MODE_TYPE,
25
+ REACT_SUSPENSE_TYPE,
26
} from 'shared/ReactSymbols';
27
import isValidElementType from 'shared/isValidElementType';
28
import lowPriorityWarning from 'shared/lowPriorityWarning';
@@ -38,6 +40,7 @@ export function typeOf(object: any) {
40
case REACT_FRAGMENT_TYPE:
41
case REACT_PROFILER_TYPE:
42
case REACT_STRICT_MODE_TYPE:
43
+ case REACT_SUSPENSE_TYPE:
44
return type;
45
default:
46
const $$typeofType = type && type.$$typeof;
@@ -51,6 +54,7 @@ export function typeOf(object: any) {
54
return $$typeof;
55
}
56
}
57
+ case REACT_LAZY_TYPE:
58
case REACT_MEMO_TYPE:
59
case REACT_PORTAL_TYPE:
60
return $$typeof;
@@ -68,10 +72,12 @@ export const ContextProvider = REACT_PROVIDER_TYPE;
72
export const Element = REACT_ELEMENT_TYPE;
73
export const ForwardRef = REACT_FORWARD_REF_TYPE;
74
export const Fragment = REACT_FRAGMENT_TYPE;
71
-export const Profiler = REACT_PROFILER_TYPE;
72
-export const Portal = REACT_PORTAL_TYPE;
75
+export const Lazy = REACT_LAZY_TYPE;
76
export const Memo = REACT_MEMO_TYPE;
77
+export const Portal = REACT_PORTAL_TYPE;
78
+export const Profiler = REACT_PROFILER_TYPE;
79
export const StrictMode = REACT_STRICT_MODE_TYPE;
80
+export const Suspense = REACT_SUSPENSE_TYPE;
81
82
export {isValidElementType};
83
@@ -114,8 +120,8 @@ export function isForwardRef(object: any) {
120
export function isFragment(object: any) {
121
return typeOf(object) === REACT_FRAGMENT_TYPE;
122
}
117
-export function isProfiler(object: any) {
118
- return typeOf(object) === REACT_PROFILER_TYPE;
123
+export function isLazy(object: any) {
124
+ return typeOf(object) === REACT_LAZY_TYPE;
125
}
126
export function isMemo(object: any) {
127
return typeOf(object) === REACT_MEMO_TYPE;
@@ -123,6 +129,12 @@ export function isMemo(object: any) {
129
export function isPortal(object: any) {
130
return typeOf(object) === REACT_PORTAL_TYPE;
131
}
132
+export function isProfiler(object: any) {
133
+ return typeOf(object) === REACT_PROFILER_TYPE;
134
+}
135
export function isStrictMode(object: any) {
136
return typeOf(object) === REACT_STRICT_MODE_TYPE;
137
}
138
+export function isSuspense(object: any) {
139
+ return typeOf(object) === REACT_SUSPENSE_TYPE;
140
+}
packages/react-is/src/__tests__/ReactIs-test.js
+22
-2
@@ -39,17 +39,19 @@ describe('ReactIs', () => {
39
}
40
41
const FunctionComponent = () => React.createElement('div');
42
-
42
const ForwardRefComponent = React.forwardRef((props, ref) =>
43
React.createElement(Component, {forwardedRef: ref, ...props}),
44
);
46
-
45
+ const LazyComponent = React.lazy(() => Component);
46
+ const MemoComponent = React.memo(Component);
47
const Context = React.createContext(false);
48
49
expect(ReactIs.isValidElementType('div')).toEqual(true);
50
expect(ReactIs.isValidElementType(Component)).toEqual(true);
51
expect(ReactIs.isValidElementType(FunctionComponent)).toEqual(true);
52
expect(ReactIs.isValidElementType(ForwardRefComponent)).toEqual(true);
53
+ expect(ReactIs.isValidElementType(LazyComponent)).toEqual(true);
54
+ expect(ReactIs.isValidElementType(MemoComponent)).toEqual(true);
55
expect(ReactIs.isValidElementType(Context.Provider)).toEqual(true);
56
expect(ReactIs.isValidElementType(Context.Consumer)).toEqual(true);
57
expect(ReactIs.isValidElementType(React.createFactory('div'))).toEqual(
@@ -60,6 +62,7 @@ describe('ReactIs', () => {
62
true,
63
);
64
expect(ReactIs.isValidElementType(React.StrictMode)).toEqual(true);
65
+ expect(ReactIs.isValidElementType(React.Suspense)).toEqual(true);
66
67
expect(ReactIs.isValidElementType(true)).toEqual(false);
68
expect(ReactIs.isValidElementType(123)).toEqual(false);
@@ -116,6 +119,7 @@ describe('ReactIs', () => {
119
expect(ReactIs.isElement(<React.Fragment />)).toBe(true);
120
expect(ReactIs.isElement(<React.unstable_ConcurrentMode />)).toBe(true);
121
expect(ReactIs.isElement(<React.StrictMode />)).toBe(true);
122
+ expect(ReactIs.isElement(<React.Suspense />)).toBe(true);
123
});
124
125
it('should identify ref forwarding component', () => {
@@ -152,6 +156,14 @@ describe('ReactIs', () => {
156
expect(ReactIs.isMemo(Component)).toBe(false);
157
});
158
159
+ it('should identify lazy', () => {
160
+ const Component = () => React.createElement('div');
161
+ const lazyComponent = React.lazy(() => Component);
162
+ expect(ReactIs.typeOf(lazyComponent)).toBe(ReactIs.Lazy);
163
+ expect(ReactIs.isLazy(lazyComponent)).toBe(true);
164
+ expect(ReactIs.isLazy(Component)).toBe(false);
165
+ });
166
+
167
it('should identify strict mode', () => {
168
expect(ReactIs.typeOf(<React.StrictMode />)).toBe(ReactIs.StrictMode);
169
expect(ReactIs.isStrictMode(<React.StrictMode />)).toBe(true);
@@ -160,6 +172,14 @@ describe('ReactIs', () => {
172
expect(ReactIs.isStrictMode(<div />)).toBe(false);
173
});
174
175
+ it('should identify suspense', () => {
176
+ expect(ReactIs.typeOf(<React.Suspense />)).toBe(ReactIs.Suspense);
177
+ expect(ReactIs.isSuspense(<React.Suspense />)).toBe(true);
178
+ expect(ReactIs.isSuspense({type: ReactIs.Suspense})).toBe(false);
179
+ expect(ReactIs.isSuspense('React.Suspense')).toBe(false);
180
+ expect(ReactIs.isSuspense(<div />)).toBe(false);
181
+ });
182
+
183
it('should identify profile root', () => {
184
expect(
185
ReactIs.typeOf(<React.unstable_Profiler id="foo" onRender={jest.fn()} />),