mirror of
https://github.com/hanzoai/react.git
synced 2026-09-24 17:02:27 +00:00
[DevTools] Show name prop of Suspense / Activity in the Components Tree view (#34135)
The name prop will be used in the Suspense tab to help identity a boundary. Activity will also allow names. A custom component can be identified by the name of the component but built-ins doesn't have that. This PR adds it to the Components Tree View as well since otherwise you only have the key to go on. Normally we don't add all the props to avoid making this view too noisy but this is an exception along with key to help identify a boundary quickly in the tree. Unlike the SuspenseNode store, this wouldn't ever have a name inferred by owner since that kind of context already exists in this view. <img width="600" height="161" alt="Screenshot 2025-08-08 at 1 20 36 PM" src="https://github.com/user-attachments/assets/fe50d624-887a-4b9d-9186-75f131f83195" /> I also made both the key and name prop searchable. <img width="608" height="206" alt="Screenshot 2025-08-08 at 1 32 27 PM" src="https://github.com/user-attachments/assets/d3502d9c-7614-45fc-b973-57f06dd9cddc" />
This commit is contained in:
committed by
GitHub
parent
b42a225d63
commit
0bd8e090aa
@@ -2369,6 +2369,15 @@ export function attach(
|
||||
const keyString = key === null ? null : String(key);
|
||||
const keyStringID = getStringID(keyString);
|
||||
|
||||
const nameProp =
|
||||
fiber.tag === SuspenseComponent
|
||||
? fiber.memoizedProps.name
|
||||
: fiber.tag === ActivityComponent
|
||||
? fiber.memoizedProps.name
|
||||
: null;
|
||||
const namePropString = nameProp == null ? null : String(nameProp);
|
||||
const namePropStringID = getStringID(namePropString);
|
||||
|
||||
pushOperation(TREE_OPERATION_ADD);
|
||||
pushOperation(id);
|
||||
pushOperation(elementType);
|
||||
@@ -2376,6 +2385,7 @@ export function attach(
|
||||
pushOperation(ownerID);
|
||||
pushOperation(displayNameStringID);
|
||||
pushOperation(keyStringID);
|
||||
pushOperation(namePropStringID);
|
||||
|
||||
// If this subtree has a new mode, let the frontend know.
|
||||
if ((fiber.mode & StrictModeBits) !== 0) {
|
||||
@@ -2478,6 +2488,7 @@ export function attach(
|
||||
// in such a way as to bypass the default stringification of the "key" property.
|
||||
const keyString = key === null ? null : String(key);
|
||||
const keyStringID = getStringID(keyString);
|
||||
const namePropStringID = getStringID(null);
|
||||
|
||||
const id = instance.id;
|
||||
|
||||
@@ -2488,6 +2499,7 @@ export function attach(
|
||||
pushOperation(ownerID);
|
||||
pushOperation(displayNameStringID);
|
||||
pushOperation(keyStringID);
|
||||
pushOperation(namePropStringID);
|
||||
|
||||
const componentLogsEntry =
|
||||
componentInfoToComponentLogsMap.get(componentInfo);
|
||||
|
||||
@@ -426,6 +426,7 @@ export function attach(
|
||||
pushOperation(ownerID);
|
||||
pushOperation(displayNameStringID);
|
||||
pushOperation(keyStringID);
|
||||
pushOperation(getStringID(null)); // name prop
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1116,6 +1116,7 @@ export default class Store extends EventEmitter<{
|
||||
isCollapsed: false, // Never collapse roots; it would hide the entire tree.
|
||||
isStrictModeNonCompliant,
|
||||
key: null,
|
||||
nameProp: null,
|
||||
ownerID: 0,
|
||||
parentID: 0,
|
||||
type,
|
||||
@@ -1139,6 +1140,10 @@ export default class Store extends EventEmitter<{
|
||||
const key = stringTable[keyStringID];
|
||||
i++;
|
||||
|
||||
const namePropStringID = operations[i];
|
||||
const nameProp = stringTable[namePropStringID];
|
||||
i++;
|
||||
|
||||
if (__DEBUG__) {
|
||||
debug(
|
||||
'Add',
|
||||
@@ -1180,6 +1185,7 @@ export default class Store extends EventEmitter<{
|
||||
isCollapsed: this._collapseNodesByDefault,
|
||||
isStrictModeNonCompliant: parentElement.isStrictModeNonCompliant,
|
||||
key,
|
||||
nameProp,
|
||||
ownerID,
|
||||
parentID,
|
||||
type,
|
||||
|
||||
@@ -119,6 +119,7 @@ export default function Element({data, index, style}: Props): React.Node {
|
||||
hocDisplayNames,
|
||||
isStrictModeNonCompliant,
|
||||
key,
|
||||
nameProp,
|
||||
compiledWithForget,
|
||||
} = element;
|
||||
const {
|
||||
@@ -179,7 +180,24 @@ export default function Element({data, index, style}: Props): React.Node {
|
||||
className={styles.KeyValue}
|
||||
title={key}
|
||||
onDoubleClick={handleKeyDoubleClick}>
|
||||
<pre>{key}</pre>
|
||||
<pre>
|
||||
<IndexableDisplayName displayName={key} id={id} />
|
||||
</pre>
|
||||
</span>
|
||||
"
|
||||
</Fragment>
|
||||
)}
|
||||
|
||||
{nameProp && (
|
||||
<Fragment>
|
||||
<span className={styles.KeyName}>name</span>="
|
||||
<span
|
||||
className={styles.KeyValue}
|
||||
title={nameProp}
|
||||
onDoubleClick={handleKeyDoubleClick}>
|
||||
<pre>
|
||||
<IndexableDisplayName displayName={nameProp} id={id} />
|
||||
</pre>
|
||||
</span>
|
||||
"
|
||||
</Fragment>
|
||||
|
||||
+12
-1
@@ -995,7 +995,14 @@ function recursivelySearchTree(
|
||||
return;
|
||||
}
|
||||
|
||||
const {children, displayName, hocDisplayNames, compiledWithForget} = element;
|
||||
const {
|
||||
children,
|
||||
displayName,
|
||||
hocDisplayNames,
|
||||
compiledWithForget,
|
||||
key,
|
||||
nameProp,
|
||||
} = element;
|
||||
if (displayName != null && regExp.test(displayName) === true) {
|
||||
searchResults.push(elementID);
|
||||
} else if (
|
||||
@@ -1006,6 +1013,10 @@ function recursivelySearchTree(
|
||||
searchResults.push(elementID);
|
||||
} else if (compiledWithForget && regExp.test('Forget')) {
|
||||
searchResults.push(elementID);
|
||||
} else if (typeof key === 'string' && regExp.test(key)) {
|
||||
searchResults.push(elementID);
|
||||
} else if (typeof nameProp === 'string' && regExp.test(nameProp)) {
|
||||
searchResults.push(elementID);
|
||||
}
|
||||
|
||||
children.forEach(childID =>
|
||||
|
||||
+3
@@ -239,6 +239,9 @@ function updateTree(
|
||||
const key = stringTable[keyStringID];
|
||||
i++;
|
||||
|
||||
// skip name prop
|
||||
i++;
|
||||
|
||||
if (__DEBUG__) {
|
||||
debug(
|
||||
'Add',
|
||||
|
||||
@@ -157,6 +157,7 @@ export type Element = {
|
||||
type: ElementType,
|
||||
displayName: string | null,
|
||||
key: number | string | null,
|
||||
nameProp: null | string,
|
||||
|
||||
hocDisplayNames: null | Array<string>,
|
||||
|
||||
|
||||
+1
@@ -271,6 +271,7 @@ export function printOperationsArray(operations: Array<number>) {
|
||||
i++;
|
||||
|
||||
i++; // key
|
||||
i++; // name
|
||||
|
||||
logs.push(
|
||||
`Add node ${id} (${displayName || 'null'}) as child of ${parentID}`,
|
||||
|
||||
@@ -298,6 +298,7 @@ export type ViewTransitionProps = {
|
||||
export type ActivityProps = {
|
||||
mode?: 'hidden' | 'visible' | null | void,
|
||||
children?: ReactNodeList,
|
||||
name?: string,
|
||||
};
|
||||
|
||||
export type SuspenseProps = {
|
||||
|
||||
Reference in New Issue
Block a user