diff --git a/packages/react-devtools-shared/src/__tests__/__snapshots__/store-test.js.snap b/packages/react-devtools-shared/src/__tests__/__snapshots__/store-test.js.snap index 43a7658fa79b8..a649c7d1f51bf 100644 --- a/packages/react-devtools-shared/src/__tests__/__snapshots__/store-test.js.snap +++ b/packages/react-devtools-shared/src/__tests__/__snapshots__/store-test.js.snap @@ -612,3 +612,15 @@ exports[`Store should properly serialize non-string key values: 1: mount 1`] = ` [root] `; + +exports[`Store should show the right display names for special component types 1`] = ` +[root] + ▾ + + [ForwardRef] + [Memo] + ▾ [Memo] + [ForwardRef] + ▾ + +`; diff --git a/packages/react-devtools-shared/src/__tests__/store-test.js b/packages/react-devtools-shared/src/__tests__/store-test.js index 6525e94427c65..b7a5021df0ae8 100644 --- a/packages/react-devtools-shared/src/__tests__/store-test.js +++ b/packages/react-devtools-shared/src/__tests__/store-test.js @@ -848,4 +848,42 @@ describe('Store', () => { act(() => ReactDOM.render([fauxElement], document.createElement('div'))); expect(store).toMatchSnapshot('1: mount'); }); + + it('should show the right display names for special component types', async done => { + async function fakeImport(result) { + return {default: result}; + } + + const MyComponent = (props, ref) => null; + const FowardRefComponent = React.forwardRef(MyComponent); + const MemoComponent = React.memo(MyComponent); + const MemoForwardRefComponent = React.memo(FowardRefComponent); + const LazyComponent = React.lazy(() => fakeImport(MyComponent)); + + const App = () => ( + + + + + + + + + + ); + + const container = document.createElement('div'); + + // Render once to start fetching the lazy component + act(() => ReactDOM.render(, container)); + + await Promise.resolve(); + + // Render again after it resolves + act(() => ReactDOM.render(, container)); + + expect(store).toMatchSnapshot(); + + done(); + }); }); diff --git a/packages/react-devtools-shared/src/backend/renderer.js b/packages/react-devtools-shared/src/backend/renderer.js index d12215c03369a..90d7958fbad78 100644 --- a/packages/react-devtools-shared/src/backend/renderer.js +++ b/packages/react-devtools-shared/src/backend/renderer.js @@ -331,11 +331,6 @@ export function getInternalReactConstants( } = ReactSymbols; function resolveFiberType(type: any) { - // This is to support lazy components with a Promise as the type. - // see https://github.com/facebook/react/pull/13397 - if (typeof type.then === 'function') { - return type._reactResult; - } const typeSymbol = getTypeSymbol(type); switch (typeSymbol) { case MEMO_NUMBER: diff --git a/packages/react-devtools-shared/src/devtools/utils.js b/packages/react-devtools-shared/src/devtools/utils.js index 0eb75451f2b6c..e7e8d9137c3a9 100644 --- a/packages/react-devtools-shared/src/devtools/utils.js +++ b/packages/react-devtools-shared/src/devtools/utils.js @@ -7,6 +7,11 @@ * @flow */ +import { + ElementTypeForwardRef, + ElementTypeMemo, +} from 'react-devtools-shared/src/types'; + import type {Element} from './views/Components/types'; import type Store from './store'; @@ -21,10 +26,25 @@ export function printElement(element: Element, includeWeight: boolean = false) { key = ` key="${element.key}"`; } - let hocs = ''; + let hocDisplayNames = null; if (element.hocDisplayNames !== null) { - hocs = ` [${element.hocDisplayNames.join('][')}]`; + hocDisplayNames = [...element.hocDisplayNames]; } + if (element.type === ElementTypeMemo) { + if (hocDisplayNames === null) { + hocDisplayNames = ['Memo']; + } else { + hocDisplayNames.push('Memo'); + } + } else if (element.type === ElementTypeForwardRef) { + if (hocDisplayNames === null) { + hocDisplayNames = ['ForwardRef']; + } else { + hocDisplayNames.push('ForwardRef'); + } + } + + let hocs = hocDisplayNames === null ? '' : ` [${hocDisplayNames.join('][')}]`; let suffix = ''; if (includeWeight) {