From c55be004a740af82e6142b443ffd0f1f2a480a61 Mon Sep 17 00:00:00 2001 From: Waseem Dahman Date: Mon, 4 Nov 2019 22:53:29 -0500 Subject: [PATCH] [react-devtools-shared] add resolveFiberType and resolve fiber type of memo recursively Resolving the fiber type of memo recursively before passing it to getDisplayName will prevent it from displaying "Anonymous" as displayName for components wrapped with both memo and forwardRef: memo(forwardRef(Component)) --- .../src/backend/renderer.js | 34 ++++++++++++++----- packages/react-devtools-shared/src/utils.js | 6 ---- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/packages/react-devtools-shared/src/backend/renderer.js b/packages/react-devtools-shared/src/backend/renderer.js index bc21b4c9dfa8..5dbd77362fea 100644 --- a/packages/react-devtools-shared/src/backend/renderer.js +++ b/packages/react-devtools-shared/src/backend/renderer.js @@ -49,6 +49,7 @@ import { patch as patchConsole, registerRenderer as registerRendererWithConsole, } from './console'; +import {isMemo, isForwardRef} from 'react-is'; import type {Fiber} from 'react-reconciler/src/ReactFiber'; import type { @@ -326,17 +327,29 @@ export function getInternalReactConstants( SCOPE_SYMBOL_STRING, } = 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; + } + if (isForwardRef(type)) { + return type.render; + } + // recursively resolving memo type in case of memo(forwardRef(Component)) + if (isMemo(type)) { + return resolveFiberType(type.type); + } + return type; + } + // NOTICE Keep in sync with shouldFilterFiber() and other get*ForFiber methods function getDisplayNameForFiber(fiber: Fiber): string | null { - const {type, tag} = fiber; + const {elementType, type, tag} = fiber; - // This is to support lazy components with a Promise as the type. - // see https://github.com/facebook/react/pull/13397 let resolvedType = type; if (typeof type === 'object' && type !== null) { - if (typeof type.then === 'function') { - resolvedType = type._reactResult; - } + resolvedType = resolveFiberType(type); } let resolvedContext: any = null; @@ -348,8 +361,6 @@ export function getInternalReactConstants( case FunctionComponent: case IndeterminateComponent: return getDisplayName(resolvedType); - case MemoComponent: - case SimpleMemoComponent: case ForwardRef: return ( resolvedType.displayName || getDisplayName(resolvedType, 'Anonymous') @@ -362,6 +373,13 @@ export function getInternalReactConstants( case HostText: case Fragment: return null; + case MemoComponent: + case SimpleMemoComponent: + if (elementType.displayName) { + return elementType.displayName; + } else { + return getDisplayName(resolvedType, 'Anonymous'); + } case SuspenseComponent: return 'Suspense'; case SuspenseListComponent: diff --git a/packages/react-devtools-shared/src/utils.js b/packages/react-devtools-shared/src/utils.js index 672ba75cf21d..5c22b92100b6 100644 --- a/packages/react-devtools-shared/src/utils.js +++ b/packages/react-devtools-shared/src/utils.js @@ -29,8 +29,6 @@ import { } from 'react-devtools-shared/src/types'; import {localStorageGetItem, localStorageSetItem} from './storage'; -import {isMemo, isForwardRef} from 'react-is'; - import type {ComponentFilter, ElementType} from './types'; const cachedDisplayNames: WeakMap = new WeakMap(); @@ -57,10 +55,6 @@ export function getDisplayName( displayName = type.displayName; } else if (typeof type.name === 'string' && type.name !== '') { displayName = type.name; - } else if (isMemo(type)) { - displayName = getDisplayName(type.type); - } else if (isForwardRef(type)) { - displayName = getDisplayName(type.render); } cachedDisplayNames.set(type, displayName);