Skip to content

Commit c55be00

Browse files
committed
[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))
1 parent 04341d4 commit c55be00

File tree

2 files changed

+26
-14
lines changed

2 files changed

+26
-14
lines changed

packages/react-devtools-shared/src/backend/renderer.js

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ import {
4949
patch as patchConsole,
5050
registerRenderer as registerRendererWithConsole,
5151
} from './console';
52+
import {isMemo, isForwardRef} from 'react-is';
5253

5354
import type {Fiber} from 'react-reconciler/src/ReactFiber';
5455
import type {
@@ -326,17 +327,29 @@ export function getInternalReactConstants(
326327
SCOPE_SYMBOL_STRING,
327328
} = ReactSymbols;
328329

330+
function resolveFiberType(type: any) {
331+
// This is to support lazy components with a Promise as the type.
332+
// see https://github.com/facebook/react/pull/13397
333+
if (typeof type.then === 'function') {
334+
return type._reactResult;
335+
}
336+
if (isForwardRef(type)) {
337+
return type.render;
338+
}
339+
// recursively resolving memo type in case of memo(forwardRef(Component))
340+
if (isMemo(type)) {
341+
return resolveFiberType(type.type);
342+
}
343+
return type;
344+
}
345+
329346
// NOTICE Keep in sync with shouldFilterFiber() and other get*ForFiber methods
330347
function getDisplayNameForFiber(fiber: Fiber): string | null {
331-
const {type, tag} = fiber;
348+
const {elementType, type, tag} = fiber;
332349

333-
// This is to support lazy components with a Promise as the type.
334-
// see https://github.com/facebook/react/pull/13397
335350
let resolvedType = type;
336351
if (typeof type === 'object' && type !== null) {
337-
if (typeof type.then === 'function') {
338-
resolvedType = type._reactResult;
339-
}
352+
resolvedType = resolveFiberType(type);
340353
}
341354

342355
let resolvedContext: any = null;
@@ -348,8 +361,6 @@ export function getInternalReactConstants(
348361
case FunctionComponent:
349362
case IndeterminateComponent:
350363
return getDisplayName(resolvedType);
351-
case MemoComponent:
352-
case SimpleMemoComponent:
353364
case ForwardRef:
354365
return (
355366
resolvedType.displayName || getDisplayName(resolvedType, 'Anonymous')
@@ -362,6 +373,13 @@ export function getInternalReactConstants(
362373
case HostText:
363374
case Fragment:
364375
return null;
376+
case MemoComponent:
377+
case SimpleMemoComponent:
378+
if (elementType.displayName) {
379+
return elementType.displayName;
380+
} else {
381+
return getDisplayName(resolvedType, 'Anonymous');
382+
}
365383
case SuspenseComponent:
366384
return 'Suspense';
367385
case SuspenseListComponent:

packages/react-devtools-shared/src/utils.js

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,6 @@ import {
2929
} from 'react-devtools-shared/src/types';
3030
import {localStorageGetItem, localStorageSetItem} from './storage';
3131

32-
import {isMemo, isForwardRef} from 'react-is';
33-
3432
import type {ComponentFilter, ElementType} from './types';
3533

3634
const cachedDisplayNames: WeakMap<Function, string> = new WeakMap();
@@ -57,10 +55,6 @@ export function getDisplayName(
5755
displayName = type.displayName;
5856
} else if (typeof type.name === 'string' && type.name !== '') {
5957
displayName = type.name;
60-
} else if (isMemo(type)) {
61-
displayName = getDisplayName(type.type);
62-
} else if (isForwardRef(type)) {
63-
displayName = getDisplayName(type.render);
6458
}
6559

6660
cachedDisplayNames.set(type, displayName);

0 commit comments

Comments
 (0)