@samitouri / QOS-React / commits / 7f1531044b

Differentiate between no-change and no-element-found when inspecting element

Brian Vaughn committed Apr 22, 2019 at 15:37 UTC 7f1531044b9f40e88b949dbe72e40e484c931465
4 files changed +54 -37
src/backend/renderer.js
+16 -10
@@ -40,7 +40,10 @@ import type {
40 ReactRenderer,
41 RendererInterface,
42 } from './types';
43 -import type { InspectedElement } from 'src/devtools/views/Components/types';
43 +import type {
44 + InspectedElement,
45 + InspectedElementResponse,
46 +} from 'src/devtools/views/Components/types';
47
48 function getInternalReactConstants(version) {
49 const ReactSymbols = {
@@ -1649,27 +1652,30 @@ export function attach(
1652 let inspectedElementID: number | null = null;
1653 let hasInspectedElementChanged: boolean = false;
1654
1652 - function inspectElement(id: number): InspectedElement | null {
1655 + function inspectElement(id: number): InspectedElementResponse | null {
1656 if (inspectedElementID === id && !hasInspectedElementChanged) {
1657 // Optimization: Don't resend (and reserialize) unchanged props.
1655 - return null;
1658 + return {
1659 + id,
1660 + inspectedElement: null,
1661 + };
1662 }
1663
1664 inspectedElementID = id;
1665 hasInspectedElementChanged = false;
1666
1661 - let result = inspectElementRaw(id);
1662 - if (result === null) {
1667 + let inspectedElement = inspectElementRaw(id);
1668 + if (inspectedElement === null) {
1669 return null;
1670 }
1671
1672 // TODO Review sanitization approach for the below inspectable values.
1667 - result.context = cleanForBridge(result.context);
1668 - result.hooks = cleanForBridge(result.hooks);
1669 - result.props = cleanForBridge(result.props);
1670 - result.state = cleanForBridge(result.state);
1673 + inspectedElement.context = cleanForBridge(inspectedElement.context);
1674 + inspectedElement.hooks = cleanForBridge(inspectedElement.hooks);
1675 + inspectedElement.props = cleanForBridge(inspectedElement.props);
1676 + inspectedElement.state = cleanForBridge(inspectedElement.state);
1677
1672 - return result;
1678 + return { id, inspectedElement };
1679 }
1680
1681 function logElementToConsole(id) {
src/backend/types.js
+2 -2
@@ -1,7 +1,7 @@
1 // @flow
2
3 import type { ElementType } from 'src/devtools/types';
4 -import type { InspectedElement } from 'src/devtools/views/Components/types';
4 +import type { InspectedElementResponse } from 'src/devtools/views/Components/types';
5
6 type BundleType =
7 | 0 // PROD
@@ -105,7 +105,7 @@ export type RendererInterface = {
105 getProfilingSummary: (rootID: number) => ProfilingSummary,
106 handleCommitFiberRoot: (fiber: Object) => void,
107 handleCommitFiberUnmount: (fiber: Object) => void,
108 - inspectElement: (id: number) => InspectedElement | null,
108 + inspectElement: (id: number) => InspectedElementResponse | null,
109 logElementToConsole: (id: number) => void,
110 overrideSuspense: (id: number, forceFallback: boolean) => void,
111 prepareViewElementSource: (id: number) => void,
src/devtools/views/Components/InspectedElementContext.js
+31 -25
@@ -15,6 +15,7 @@ import { TreeStateContext } from './TreeContext';
15 import type {
16 DehydratedData,
17 InspectedElement,
18 + InspectedElementResponse,
19 } from 'src/devtools/views/Components/types';
20 import type { Resource } from '../../cache';
21
@@ -70,29 +71,32 @@ function InspectedElementContextController({ children }: Props) {
71 // This effect handler invalidates the suspense cache and schedules rendering updates with React.
72 useEffect(() => {
73 const onInspectedElement = (
73 - inspectedElementRaw: InspectedElement | null
74 + inspectedElementResponse: InspectedElementResponse | null
75 ) => {
75 - if (inspectedElementRaw != null) {
76 - const id = inspectedElementRaw.id;
77 -
78 - const inspectedElement = (({
79 - ...inspectedElementRaw,
80 - context: hydrateHelper(inspectedElementRaw.context),
81 - hooks: hydrateHelper(inspectedElementRaw.hooks),
82 - props: hydrateHelper(inspectedElementRaw.props),
83 - state: hydrateHelper(inspectedElementRaw.state),
84 - }: any): InspectedElement);
85 -
86 - const request = inProgressRequests.get(id);
87 - if (request != null) {
88 - inProgressRequests.delete(id);
89 - request.resolveFn(inspectedElement);
90 - } else {
91 - resource.write(id, inspectedElement);
92 -
93 - // Schedule update with React if the curently-selected element has been invalidated.
94 - if (id === selectedElementID) {
95 - setCount(count => count + 1);
76 + if (inspectedElementResponse != null) {
77 + let { inspectedElement } = inspectedElementResponse;
78 + if (inspectedElement !== null) {
79 + const id = inspectedElement.id;
80 +
81 + inspectedElement = (({
82 + ...inspectedElement,
83 + context: hydrateHelper(inspectedElement.context),
84 + hooks: hydrateHelper(inspectedElement.hooks),
85 + props: hydrateHelper(inspectedElement.props),
86 + state: hydrateHelper(inspectedElement.state),
87 + }: any): InspectedElement);
88 +
89 + const request = inProgressRequests.get(id);
90 + if (request != null) {
91 + inProgressRequests.delete(id);
92 + request.resolveFn(inspectedElement);
93 + } else {
94 + resource.write(id, inspectedElement);
95 +
96 + // Schedule update with React if the curently-selected element has been invalidated.
97 + if (id === selectedElementID) {
98 + setCount(count => count + 1);
99 + }
100 }
101 }
102 }
@@ -122,10 +126,12 @@ function InspectedElementContextController({ children }: Props) {
126 // We'll poll for an update in the response handler below.
127 sendRequest();
128
125 - const onInspectedElement = (inspectedElement: InspectedElement | null) => {
129 + const onInspectedElement = (
130 + inspectedElementResponse: InspectedElementResponse | null
131 + ) => {
132 if (
127 - inspectedElement !== null &&
128 - inspectedElement.id === selectedElementID
133 + inspectedElementResponse !== null &&
134 + inspectedElementResponse.id === selectedElementID
135 ) {
136 // If this is the element we requested, wait a little bit and then ask for an update.
137 timeoutID = setTimeout(sendRequest, 1000);
src/devtools/views/Components/types.js
+5
@@ -65,6 +65,11 @@ export type InspectedElement = {|
65 source: Object | null,
66 |};
67
68 +export type InspectedElementResponse = {|
69 + id: number,
70 + inspectedElement: InspectedElement | null,
71 +|};
72 +
73 // TODO: Add profiling type
74
75 export type DehydratedData = {|