DevTools: Add root and renderer version to inspected props panel (#18963)

* DevTools: Add root and renderer version to inspected props panel
* Removed redundant .length check
This commit is contained in:
Brian Vaughn 2020-05-21 14:40:49 -07:00 committed by GitHub
parent 74394aa8cb
commit aefb97e6bb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 111 additions and 18 deletions

View File

@ -802,6 +802,10 @@ export function attach(
// Location of component in source coude.
source,
rootType: null,
rendererPackageName: null,
rendererVersion: null,
};
}

View File

@ -2278,6 +2278,16 @@ export function attach(
}
}
let rootType = null;
let current = fiber;
while (current.return !== null) {
current = current.return;
}
const fiberRoot = current.stateNode;
if (fiberRoot != null && fiberRoot._debugRootType !== null) {
rootType = fiberRoot._debugRootType;
}
return {
id,
@ -2318,6 +2328,10 @@ export function attach(
// Location of component in source coude.
source: _debugSource || null,
rootType,
rendererPackageName: renderer.rendererPackageName,
rendererVersion: renderer.version,
};
}

View File

@ -87,6 +87,7 @@ export type ReactProviderType<T> = {
export type ReactRenderer = {
findFiberByHostInstance: (hostInstance: NativeType) => ?Fiber,
version: string,
rendererPackageName: string,
bundleType: BundleType,
// 16.9+
overrideHookState?: ?(
@ -207,10 +208,17 @@ export type InspectedElement = {|
// List of owners
owners: Array<Owner> | null,
// Location of component in source coude.
// Location of component in source code.
source: Source | null,
type: ElementType,
// Meta information about the root this element belongs to.
rootType: string | null,
// Meta information about the renderer that created this element.
rendererPackageName: string | null,
rendererVersion: string | null,
|};
export const InspectElementFullDataType = 'full-data';

View File

@ -26,12 +26,12 @@ export default function Badge({
type,
children,
}: Props) {
let totalBadgeCount = 0;
if (hocDisplayNames !== null) {
totalBadgeCount += hocDisplayNames.length;
if (hocDisplayNames === null) {
return null;
}
const totalBadgeCount = hocDisplayNames.length;
return (
<Fragment>
<div className={`${styles.Badge} ${className || ''}`}>{children}</div>

View File

@ -208,6 +208,9 @@ function InspectedElementContextController({children}: Props) {
context,
hooks,
props,
rendererPackageName,
rendererVersion,
rootType,
state,
key,
} = ((data.value: any): InspectedElementBackend);
@ -220,6 +223,9 @@ function InspectedElementContextController({children}: Props) {
hasLegacyContext,
id,
key,
rendererPackageName,
rendererVersion,
rootType,
source,
type,
owners:

View File

@ -153,3 +153,10 @@
.ContextMenuIcon {
margin-right: 0.5rem;
}
.OwnersMetaField {
padding-left: 1.25rem;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}

View File

@ -45,7 +45,7 @@ import type {
InspectedElementContextType,
StoreAsGlobal,
} from './InspectedElementContext';
import type {Element, InspectedElement} from './types';
import type {Element, InspectedElement, Owner} from './types';
import type {ElementType} from 'react-devtools-shared/src/types';
export type Props = {||};
@ -291,11 +291,13 @@ function InspectedElementView({
hooks,
owners,
props,
rendererPackageName,
rendererVersion,
rootType,
source,
state,
} = inspectedElement;
const {ownerID} = useContext(TreeStateContext);
const bridge = useContext(BridgeContext);
const store = useContext(StoreContext);
@ -374,6 +376,14 @@ function InspectedElementView({
};
}
const rendererLabel =
rendererPackageName !== null && rendererVersion !== null
? `${rendererPackageName}@${rendererVersion}`
: null;
const showOwnersList = owners !== null && owners.length > 0;
const showRenderedBy =
showOwnersList || rendererLabel !== null || rootType !== null;
return (
<Fragment>
<div className={styles.InspectedElement}>
@ -415,19 +425,26 @@ function InspectedElementView({
<NativeStyleEditor />
{ownerID === null && owners !== null && owners.length > 0 && (
{showRenderedBy && (
<div className={styles.Owners}>
<div className={styles.OwnersHeader}>rendered by</div>
{owners.map(owner => (
<OwnerView
key={owner.id}
displayName={owner.displayName || 'Anonymous'}
hocDisplayNames={owner.hocDisplayNames}
id={owner.id}
isInStore={store.containsElement(owner.id)}
type={owner.type}
/>
))}
{showOwnersList &&
((owners: any): Array<Owner>).map(owner => (
<OwnerView
key={owner.id}
displayName={owner.displayName || 'Anonymous'}
hocDisplayNames={owner.hocDisplayNames}
id={owner.id}
isInStore={store.containsElement(owner.id)}
type={owner.type}
/>
))}
{rootType !== null && (
<div className={styles.OwnersMetaField}>{rootType}</div>
)}
{rendererLabel !== null && (
<div className={styles.OwnersMetaField}>{rendererLabel}</div>
)}
</div>
)}

View File

@ -88,6 +88,13 @@ export type InspectedElement = {|
source: Source | null,
type: ElementType,
// Meta information about the root this element belongs to.
rootType: string | null,
// Meta information about the renderer that created this element.
rendererPackageName: string | null,
rendererVersion: string | null,
|};
// TODO: Add profiling type

View File

@ -24,6 +24,7 @@ import {
} from 'shared/ReactFeatureFlags';
import {unstable_getThreadID} from 'scheduler/tracing';
import {initializeUpdateQueue} from './ReactUpdateQueue.new';
import {LegacyRoot, BlockingRoot, ConcurrentRoot} from './ReactRootTags';
function FiberRootNode(containerInfo, tag, hydrate) {
this.tag = tag;
@ -60,6 +61,20 @@ function FiberRootNode(containerInfo, tag, hydrate) {
if (enableSuspenseCallback) {
this.hydrationCallbacks = null;
}
if (__DEV__) {
switch (tag) {
case BlockingRoot:
this._debugRootType = 'createBlockingRoot()';
break;
case ConcurrentRoot:
this._debugRootType = 'createRoot()';
break;
case LegacyRoot:
this._debugRootType = 'createLegacyRoot()';
break;
}
}
}
export function createFiberRoot(

View File

@ -22,6 +22,7 @@ import {unstable_getThreadID} from 'scheduler/tracing';
import {NoPriority} from './SchedulerWithReactIntegration.old';
import {initializeUpdateQueue} from './ReactUpdateQueue.old';
import {clearPendingUpdates as clearPendingMutableSourceUpdates} from './ReactMutableSource.old';
import {LegacyRoot, BlockingRoot, ConcurrentRoot} from './ReactRootTags';
function FiberRootNode(containerInfo, tag, hydrate) {
this.tag = tag;
@ -54,6 +55,20 @@ function FiberRootNode(containerInfo, tag, hydrate) {
if (enableSuspenseCallback) {
this.hydrationCallbacks = null;
}
if (__DEV__) {
switch (tag) {
case BlockingRoot:
this._debugRootType = 'createBlockingRoot()';
break;
case ConcurrentRoot:
this._debugRootType = 'createRoot()';
break;
case LegacyRoot:
this._debugRootType = 'createLegacyRoot()';
break;
}
}
}
export function createFiberRoot(