diff --git a/packages/react-is/src/ReactIs.js b/packages/react-is/src/ReactIs.js index e69486610ccc4..c618f621d99c7 100644 --- a/packages/react-is/src/ReactIs.js +++ b/packages/react-is/src/ReactIs.js @@ -16,11 +16,13 @@ import { REACT_ELEMENT_TYPE, REACT_FORWARD_REF_TYPE, REACT_FRAGMENT_TYPE, + REACT_LAZY_TYPE, REACT_MEMO_TYPE, REACT_PORTAL_TYPE, REACT_PROFILER_TYPE, REACT_PROVIDER_TYPE, REACT_STRICT_MODE_TYPE, + REACT_SUSPENSE_TYPE, } from 'shared/ReactSymbols'; import isValidElementType from 'shared/isValidElementType'; import lowPriorityWarning from 'shared/lowPriorityWarning'; @@ -38,6 +40,7 @@ export function typeOf(object: any) { case REACT_FRAGMENT_TYPE: case REACT_PROFILER_TYPE: case REACT_STRICT_MODE_TYPE: + case REACT_SUSPENSE_TYPE: return type; default: const $$typeofType = type && type.$$typeof; @@ -51,6 +54,7 @@ export function typeOf(object: any) { return $$typeof; } } + case REACT_LAZY_TYPE: case REACT_MEMO_TYPE: case REACT_PORTAL_TYPE: return $$typeof; @@ -68,10 +72,12 @@ export const ContextProvider = REACT_PROVIDER_TYPE; export const Element = REACT_ELEMENT_TYPE; export const ForwardRef = REACT_FORWARD_REF_TYPE; export const Fragment = REACT_FRAGMENT_TYPE; -export const Profiler = REACT_PROFILER_TYPE; -export const Portal = REACT_PORTAL_TYPE; +export const Lazy = REACT_LAZY_TYPE; export const Memo = REACT_MEMO_TYPE; +export const Portal = REACT_PORTAL_TYPE; +export const Profiler = REACT_PROFILER_TYPE; export const StrictMode = REACT_STRICT_MODE_TYPE; +export const Suspense = REACT_SUSPENSE_TYPE; export {isValidElementType}; @@ -114,8 +120,8 @@ export function isForwardRef(object: any) { export function isFragment(object: any) { return typeOf(object) === REACT_FRAGMENT_TYPE; } -export function isProfiler(object: any) { - return typeOf(object) === REACT_PROFILER_TYPE; +export function isLazy(object: any) { + return typeOf(object) === REACT_LAZY_TYPE; } export function isMemo(object: any) { return typeOf(object) === REACT_MEMO_TYPE; @@ -123,6 +129,12 @@ export function isMemo(object: any) { export function isPortal(object: any) { return typeOf(object) === REACT_PORTAL_TYPE; } +export function isProfiler(object: any) { + return typeOf(object) === REACT_PROFILER_TYPE; +} export function isStrictMode(object: any) { return typeOf(object) === REACT_STRICT_MODE_TYPE; } +export function isSuspense(object: any) { + return typeOf(object) === REACT_SUSPENSE_TYPE; +} diff --git a/packages/react-is/src/__tests__/ReactIs-test.js b/packages/react-is/src/__tests__/ReactIs-test.js index aeb1805d2f170..9838096d3a5d4 100644 --- a/packages/react-is/src/__tests__/ReactIs-test.js +++ b/packages/react-is/src/__tests__/ReactIs-test.js @@ -39,17 +39,19 @@ describe('ReactIs', () => { } const FunctionComponent = () => React.createElement('div'); - const ForwardRefComponent = React.forwardRef((props, ref) => React.createElement(Component, {forwardedRef: ref, ...props}), ); - + const LazyComponent = React.lazy(() => Component); + const MemoComponent = React.memo(Component); const Context = React.createContext(false); expect(ReactIs.isValidElementType('div')).toEqual(true); expect(ReactIs.isValidElementType(Component)).toEqual(true); expect(ReactIs.isValidElementType(FunctionComponent)).toEqual(true); expect(ReactIs.isValidElementType(ForwardRefComponent)).toEqual(true); + expect(ReactIs.isValidElementType(LazyComponent)).toEqual(true); + expect(ReactIs.isValidElementType(MemoComponent)).toEqual(true); expect(ReactIs.isValidElementType(Context.Provider)).toEqual(true); expect(ReactIs.isValidElementType(Context.Consumer)).toEqual(true); expect(ReactIs.isValidElementType(React.createFactory('div'))).toEqual( @@ -60,6 +62,7 @@ describe('ReactIs', () => { true, ); expect(ReactIs.isValidElementType(React.StrictMode)).toEqual(true); + expect(ReactIs.isValidElementType(React.Suspense)).toEqual(true); expect(ReactIs.isValidElementType(true)).toEqual(false); expect(ReactIs.isValidElementType(123)).toEqual(false); @@ -116,6 +119,7 @@ describe('ReactIs', () => { expect(ReactIs.isElement()).toBe(true); expect(ReactIs.isElement()).toBe(true); expect(ReactIs.isElement()).toBe(true); + expect(ReactIs.isElement()).toBe(true); }); it('should identify ref forwarding component', () => { @@ -152,6 +156,14 @@ describe('ReactIs', () => { expect(ReactIs.isMemo(Component)).toBe(false); }); + it('should identify lazy', () => { + const Component = () => React.createElement('div'); + const lazyComponent = React.lazy(() => Component); + expect(ReactIs.typeOf(lazyComponent)).toBe(ReactIs.Lazy); + expect(ReactIs.isLazy(lazyComponent)).toBe(true); + expect(ReactIs.isLazy(Component)).toBe(false); + }); + it('should identify strict mode', () => { expect(ReactIs.typeOf()).toBe(ReactIs.StrictMode); expect(ReactIs.isStrictMode()).toBe(true); @@ -160,6 +172,14 @@ describe('ReactIs', () => { expect(ReactIs.isStrictMode(
)).toBe(false); }); + it('should identify suspense', () => { + expect(ReactIs.typeOf()).toBe(ReactIs.Suspense); + expect(ReactIs.isSuspense()).toBe(true); + expect(ReactIs.isSuspense({type: ReactIs.Suspense})).toBe(false); + expect(ReactIs.isSuspense('React.Suspense')).toBe(false); + expect(ReactIs.isSuspense(
)).toBe(false); + }); + it('should identify profile root', () => { expect( ReactIs.typeOf(),