Skip to content

Commit ecd1885

Browse files
committed
fix: also handle memod composite components
1 parent 3d95522 commit ecd1885

File tree

5 files changed

+52
-24
lines changed

5 files changed

+52
-24
lines changed

src/core/instrumentation/fiber.ts

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,22 @@
44
import type * as React from 'react';
55
import type { Fiber } from 'react-reconciler';
66

7-
const PerformedWorkFlag = 0b01;
7+
export const PerformedWorkFlag = 0b01;
88
export const ClassComponentTag = 1;
99
export const FunctionComponentTag = 0;
10-
const ContextConsumerTag = 9;
10+
export const ContextConsumerTag = 9;
1111
export const ForwardRefTag = 11;
12-
const MemoComponentTag = 14;
13-
const SimpleMemoComponentTag = 15;
14-
const HostComponentTag = 5;
15-
const HostHoistableTag = 26;
16-
const HostSingletonTag = 27;
17-
const DehydratedSuspenseComponent = 18;
18-
const HostText = 6;
19-
const Fragment = 7;
20-
const LegacyHiddenComponent = 23;
21-
const OffscreenComponent = 22;
22-
const HostRoot = 3;
12+
export const MemoComponentTag = 14;
13+
export const SimpleMemoComponentTag = 15;
14+
export const HostComponentTag = 5;
15+
export const HostHoistableTag = 26;
16+
export const HostSingletonTag = 27;
17+
export const DehydratedSuspenseComponent = 18;
18+
export const HostText = 6;
19+
export const Fragment = 7;
20+
export const LegacyHiddenComponent = 23;
21+
export const OffscreenComponent = 22;
22+
export const HostRoot = 3;
2323
export const CONCURRENT_MODE_NUMBER = 0xeacf;
2424
export const CONCURRENT_MODE_SYMBOL_STRING = 'Symbol(react.concurrent_mode)';
2525
export const DEPRECATED_ASYNC_MODE_SYMBOL_STRING = 'Symbol(react.async_mode)';

src/core/instrumentation/index.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
import type { Fiber, FiberRoot } from 'react-reconciler';
22
import * as React from 'react';
33
import { ReactScanInternals } from '../index';
4-
import { getDisplayName, fastSerialize, getType } from './utils';
4+
import {
5+
getDisplayName,
6+
fastSerialize,
7+
getType,
8+
getDisplayNameFromFiber,
9+
} from './utils';
510
import {
611
didFiberRender,
712
getSelfTime,
@@ -12,6 +17,7 @@ import {
1217
traverseState,
1318
} from './fiber';
1419
import { registerDevtoolsHook } from './init';
20+
import { isCompositeComponent } from '../web/inspect-element/utils';
1521

1622
export interface Change {
1723
name: string;
@@ -183,7 +189,7 @@ export const reportRenderFiber = (fiber: Fiber, renders: (Render | null)[]) => {
183189
count: (report?.count ?? 0) + 1,
184190
time: (report?.time ?? 0) + (time !== 0 ? time : 0.1), // .1ms lowest precision
185191
badRenders: report?.badRenders ?? [],
186-
displayName: getDisplayName(fiber.type),
192+
displayName: getDisplayNameFromFiber(fiber),
187193
});
188194
ReactScanInternals.emit(
189195
'reportDataByFiber',
@@ -229,8 +235,13 @@ export const instrument = ({
229235
const name = getDisplayName(type);
230236
if (name === 'Million(Profiler)') return;
231237
if (name) {
232-
reportRenderFiber(fiber, [propsRender, contextRender]); // back compat
233-
reportRender(name, fiber, [propsRender, contextRender]);
238+
reportRender(name, fiber, [propsRender, contextRender]); // back compat
239+
}
240+
241+
if (
242+
isCompositeComponent(fiber) // since we key on the fiber we don't need a display name (ex. memo compoenents are anonymous and dont have names)
243+
) {
244+
reportRenderFiber(fiber, [propsRender, contextRender]);
234245
}
235246

236247
if (!propsRender && !contextRender) return null;

src/core/instrumentation/utils.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import * as React from 'react';
2+
import { Fiber } from 'react-reconciler';
3+
import { MemoComponentTag, SimpleMemoComponentTag } from './fiber';
24

35
export const fastSerialize = (value: unknown) => {
46
switch (typeof value) {
@@ -67,3 +69,10 @@ export const getDisplayName = (type: any): string | null => {
6769
if (!type) return null;
6870
return type.displayName || type.name || null;
6971
};
72+
73+
export const getDisplayNameFromFiber = (fiber: Fiber): string | null => {
74+
if (fiber.tag === MemoComponentTag || fiber.tag === SimpleMemoComponentTag) {
75+
return 'Anonymous';
76+
}
77+
return getDisplayName(fiber.type);
78+
};

src/core/web/inspect-element/overlay.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { Fiber } from 'react-reconciler';
22
import { ReactScanInternals } from '../..';
3-
import { getDisplayName } from '../../instrumentation/utils';
3+
import { getDisplayNameFromFiber } from '../../instrumentation/utils';
44
import { getCompositeComponentFromElement } from './utils';
55

66
interface Rect {
@@ -162,9 +162,7 @@ export const drawStatsPill = (
162162
) => {
163163
const pillHeight = 24;
164164
const pillPadding = 8;
165-
const componentName = fiber
166-
? (getDisplayName(fiber) ?? 'Unknown')
167-
: 'Unknown';
165+
const componentName = fiber ? getDisplayNameFromFiber(fiber) : 'Unknown';
168166
let text = componentName;
169167
if (stats.count) {
170168
text += ` • ×${stats.count}`;

src/core/web/inspect-element/utils.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@ import {
44
FunctionComponentTag,
55
ClassComponentTag,
66
isHostComponent,
7-
ForwardRefTag,
87
traverseFiber,
8+
MemoComponentTag,
9+
SimpleMemoComponentTag,
910
} from '../../instrumentation/fiber';
1011
import { getRect } from '../outline';
1112

@@ -74,7 +75,7 @@ export const getParentCompositeFiber = (fiber: Fiber) => {
7475
let prevNonHost = null;
7576

7677
while (curr) {
77-
if (curr.tag === FunctionComponentTag || curr.tag === ClassComponentTag) {
78+
if (isCompositeComponent(curr)) {
7879
return [curr, prevNonHost] as const;
7980
}
8081
if (isHostComponent(curr)) {
@@ -101,7 +102,7 @@ export const getChangedProps = (fiber: Fiber): Set<string> => {
101102
export const getStateFromFiber = (fiber: Fiber): any => {
102103
if (!fiber) return {};
103104

104-
if (fiber.tag === FunctionComponentTag || fiber.tag === ForwardRefTag) {
105+
if (isCompositeComponent(fiber)) {
105106
// Functional component, need to traverse hooks
106107
let memoizedState = fiber.memoizedState;
107108
const state: any = {};
@@ -260,3 +261,12 @@ export const hasValidParent = () => {
260261
}
261262
return hasValidParent;
262263
};
264+
265+
export const isCompositeComponent = (fiber: Fiber) => {
266+
return (
267+
fiber.tag === FunctionComponentTag ||
268+
fiber.tag === ClassComponentTag ||
269+
fiber.tag === SimpleMemoComponentTag ||
270+
fiber.tag === MemoComponentTag
271+
);
272+
};

0 commit comments

Comments
 (0)