DevTools: Improve function props display for inspected elements (#17789)
Brian Vaughn committed
Jan 6, 2020 at 09:19 UTC
2bb227ef801c3a876d8064bc75903c29c94bc71d
7 files changed
+75
-21
packages/react-devtools-shared/src/__tests__/__snapshots__/inspectedElementContext-test.js.snap
+2
@@ -485,11 +485,13 @@ exports[`InspectedElementContext should support complex data types: 1: Inspected
485
"context": null,
486
"hooks": null,
487
"props": {
488
+ "anonymous_fn": {},
489
"array_buffer": {},
490
"array_of_arrays": [
491
{}
492
],
493
"big_int": {},
494
+ "bound_fn": {},
495
"data_view": {},
496
"date": {},
497
"fn": {},
packages/react-devtools-shared/src/__tests__/inspectedElementContext-test.js
+23
-2
@@ -538,14 +538,21 @@ describe('InspectedElementContext', () => {
538
},
539
});
540
541
+ class Class {
542
+ anonymousFunction = () => {};
543
+ }
544
+ const instance = new Class();
545
+
546
const container = document.createElement('div');
547
await utils.actAsync(() =>
548
ReactDOM.render(
549
<Example
550
+ anonymous_fn={instance.anonymousFunction}
551
array_buffer={arrayBuffer}
552
array_of_arrays={arrayOfArrays}
553
// eslint-disable-next-line no-undef
554
big_int={BigInt(123)}
555
+ bound_fn={exampleFunction.bind(this)}
556
data_view={dataView}
557
date={new Date(exampleDateISO)}
558
fn={exampleFunction}
@@ -593,9 +600,11 @@ describe('InspectedElementContext', () => {
600
expect(inspectedElement).toMatchSnapshot(`1: Inspected element ${id}`);
601
602
const {
603
+ anonymous_fn,
604
array_buffer,
605
array_of_arrays,
606
big_int,
607
+ bound_fn,
608
data_view,
609
date,
610
fn,
@@ -612,6 +621,12 @@ describe('InspectedElementContext', () => {
621
typed_array,
622
} = (inspectedElement: any).props;
623
624
+ expect(anonymous_fn[meta.inspectable]).toBe(false);
625
+ expect(anonymous_fn[meta.name]).toBe('function');
626
+ expect(anonymous_fn[meta.type]).toBe('function');
627
+ expect(anonymous_fn[meta.preview_long]).toBe('ƒ () {}');
628
+ expect(anonymous_fn[meta.preview_short]).toBe('ƒ () {}');
629
+
630
expect(array_buffer[meta.size]).toBe(3);
631
expect(array_buffer[meta.inspectable]).toBe(false);
632
expect(array_buffer[meta.name]).toBe('ArrayBuffer');
@@ -632,6 +647,12 @@ describe('InspectedElementContext', () => {
647
expect(big_int[meta.preview_long]).toBe('123n');
648
expect(big_int[meta.preview_short]).toBe('123n');
649
650
+ expect(bound_fn[meta.inspectable]).toBe(false);
651
+ expect(bound_fn[meta.name]).toBe('bound exampleFunction');
652
+ expect(bound_fn[meta.type]).toBe('function');
653
+ expect(bound_fn[meta.preview_long]).toBe('ƒ bound exampleFunction() {}');
654
+ expect(bound_fn[meta.preview_short]).toBe('ƒ bound exampleFunction() {}');
655
+
656
expect(data_view[meta.size]).toBe(3);
657
expect(data_view[meta.inspectable]).toBe(false);
658
expect(data_view[meta.name]).toBe('DataView');
@@ -651,8 +672,8 @@ describe('InspectedElementContext', () => {
672
expect(fn[meta.inspectable]).toBe(false);
673
expect(fn[meta.name]).toBe('exampleFunction');
674
expect(fn[meta.type]).toBe('function');
654
- expect(fn[meta.preview_long]).toBe('exampleFunction');
655
- expect(fn[meta.preview_short]).toBe('exampleFunction');
675
+ expect(fn[meta.preview_long]).toBe('ƒ exampleFunction() {}');
676
+ expect(fn[meta.preview_short]).toBe('ƒ exampleFunction() {}');
677
678
expect(html_element[meta.inspectable]).toBe(false);
679
expect(html_element[meta.name]).toBe('DIV');
packages/react-devtools-shared/src/__tests__/legacy/__snapshots__/inspectElement-test.js.snap
+2
@@ -126,11 +126,13 @@ Object {
126
"context": {},
127
"hooks": null,
128
"props": {
129
+ "anonymous_fn": {},
130
"array_buffer": {},
131
"array_of_arrays": [
132
{}
133
],
134
"big_int": {},
135
+ "bound_fn": {},
136
"data_view": {},
137
"date": {},
138
"fn": {},
packages/react-devtools-shared/src/__tests__/legacy/inspectElement-test.js
+23
@@ -169,13 +169,20 @@ describe('InspectedElementContext', () => {
169
},
170
});
171
172
+ class Class {
173
+ anonymousFunction = () => {};
174
+ }
175
+ const instance = new Class();
176
+
177
act(() =>
178
ReactDOM.render(
179
<Example
180
+ anonymous_fn={instance.anonymousFunction}
181
array_buffer={arrayBuffer}
182
array_of_arrays={arrayOfArrays}
183
// eslint-disable-next-line no-undef
184
big_int={BigInt(123)}
185
+ bound_fn={exampleFunction.bind(this)}
186
data_view={dataView}
187
date={new Date(123)}
188
fn={exampleFunction}
@@ -201,9 +208,11 @@ describe('InspectedElementContext', () => {
208
expect(inspectedElement).toMatchSnapshot('1: Initial inspection');
209
210
const {
211
+ anonymous_fn,
212
array_buffer,
213
array_of_arrays,
214
big_int,
215
+ bound_fn,
216
data_view,
217
date,
218
fn,
@@ -220,6 +229,12 @@ describe('InspectedElementContext', () => {
229
typed_array,
230
} = inspectedElement.value.props;
231
232
+ expect(anonymous_fn[meta.inspectable]).toBe(false);
233
+ expect(anonymous_fn[meta.name]).toBe('function');
234
+ expect(anonymous_fn[meta.type]).toBe('function');
235
+ expect(anonymous_fn[meta.preview_long]).toBe('ƒ () {}');
236
+ expect(anonymous_fn[meta.preview_short]).toBe('ƒ () {}');
237
+
238
expect(array_buffer[meta.size]).toBe(3);
239
expect(array_buffer[meta.inspectable]).toBe(false);
240
expect(array_buffer[meta.name]).toBe('ArrayBuffer');
@@ -238,6 +253,12 @@ describe('InspectedElementContext', () => {
253
expect(big_int[meta.name]).toBe('123');
254
expect(big_int[meta.type]).toBe('bigint');
255
256
+ expect(bound_fn[meta.inspectable]).toBe(false);
257
+ expect(bound_fn[meta.name]).toBe('bound exampleFunction');
258
+ expect(bound_fn[meta.type]).toBe('function');
259
+ expect(bound_fn[meta.preview_long]).toBe('ƒ bound exampleFunction() {}');
260
+ expect(bound_fn[meta.preview_short]).toBe('ƒ bound exampleFunction() {}');
261
+
262
expect(data_view[meta.size]).toBe(3);
263
expect(data_view[meta.inspectable]).toBe(false);
264
expect(data_view[meta.name]).toBe('DataView');
@@ -249,6 +270,8 @@ describe('InspectedElementContext', () => {
270
expect(fn[meta.inspectable]).toBe(false);
271
expect(fn[meta.name]).toBe('exampleFunction');
272
expect(fn[meta.type]).toBe('function');
273
+ expect(fn[meta.preview_long]).toBe('ƒ exampleFunction() {}');
274
+ expect(fn[meta.preview_short]).toBe('ƒ exampleFunction() {}');
275
276
expect(html_element[meta.inspectable]).toBe(false);
277
expect(html_element[meta.name]).toBe('DIV');
packages/react-devtools-shared/src/hydration.js
+1
-1
@@ -151,7 +151,7 @@ export function dehydrate(
151
inspectable: false,
152
preview_short: formatDataForPreview(data, false),
153
preview_long: formatDataForPreview(data, true),
154
- name: data.name,
154
+ name: data.name || 'function',
155
type,
156
};
157
packages/react-devtools-shared/src/utils.js
+1
-1
@@ -502,7 +502,7 @@ export function formatDataForPreview(
502
case 'html_element':
503
return `<${truncateForDisplay(data.tagName.toLowerCase())} />`;
504
case 'function':
505
- return truncateForDisplay(data.name);
505
+ return truncateForDisplay(`ƒ ${data.name}() {}`);
506
case 'string':
507
return `"${data}"`;
508
case 'bigint':
packages/react-devtools-shell/src/app/InspectableElements/SimpleValues.js
+23
-17
@@ -7,26 +7,32 @@
7
* @flow
8
*/
9
10
-import React from 'react';
10
+import React, {Component} from 'react';
11
12
function noop() {}
13
14
-export default function SimpleValues() {
15
- return (
16
- <ChildComponent
17
- string="abc"
18
- emptyString=""
19
- number={123}
20
- undefined={undefined}
21
- null={null}
22
- nan={NaN}
23
- infinity={Infinity}
24
- true={true}
25
- false={false}
26
- function={noop}
27
- regex={/abc[123]+/i}
28
- />
29
- );
14
+export default class SimpleValues extends Component {
15
+ anonymousFunction = () => {};
16
+
17
+ render() {
18
+ return (
19
+ <ChildComponent
20
+ string="abc"
21
+ emptyString=""
22
+ number={123}
23
+ undefined={undefined}
24
+ null={null}
25
+ nan={NaN}
26
+ infinity={Infinity}
27
+ true={true}
28
+ false={false}
29
+ function={noop}
30
+ anonymousFunction={this.anonymousFunction}
31
+ boundFunction={noop.bind(this)}
32
+ regex={/abc[123]+/i}
33
+ />
34
+ );
35
+ }
36
}
37
38
function ChildComponent(props: any) {