Skip to content

Commit ba9582d

Browse files
iChenLeiBrian Vaughn
andauthored
[devtools] Fix can't expand prop value in some scenario (#20534)
Co-authored-by: Brian Vaughn <[email protected]>
1 parent af16f75 commit ba9582d

File tree

4 files changed

+144
-5
lines changed

4 files changed

+144
-5
lines changed

packages/react-devtools-shared/src/__tests__/inspectedElement-test.js

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1168,6 +1168,83 @@ describe('InspectedElement', () => {
11681168
done();
11691169
});
11701170

1171+
it('should allow component prop value and value`s prototype has same name params.', async done => {
1172+
const testData = Object.create(
1173+
{
1174+
a: undefined,
1175+
b: Infinity,
1176+
c: NaN,
1177+
d: 'normal',
1178+
},
1179+
{
1180+
a: {
1181+
value: undefined,
1182+
writable: true,
1183+
enumerable: true,
1184+
configurable: true,
1185+
},
1186+
b: {
1187+
value: Infinity,
1188+
writable: true,
1189+
enumerable: true,
1190+
configurable: true,
1191+
},
1192+
c: {
1193+
value: NaN,
1194+
writable: true,
1195+
enumerable: true,
1196+
configurable: true,
1197+
},
1198+
d: {
1199+
value: 'normal',
1200+
writable: true,
1201+
enumerable: true,
1202+
configurable: true,
1203+
},
1204+
},
1205+
);
1206+
const Example = ({data}) => null;
1207+
const container = document.createElement('div');
1208+
await utils.actAsync(() =>
1209+
ReactDOM.render(<Example data={testData} />, container),
1210+
);
1211+
1212+
const id = ((store.getElementIDAtIndex(0): any): number);
1213+
1214+
let inspectedElement = null;
1215+
1216+
function Suspender({target}) {
1217+
inspectedElement = useInspectedElement(target);
1218+
return null;
1219+
}
1220+
1221+
await utils.actAsync(
1222+
() =>
1223+
TestRenderer.create(
1224+
<Contexts
1225+
defaultSelectedElementID={id}
1226+
defaultSelectedElementIndex={0}>
1227+
<React.Suspense fallback={null}>
1228+
<Suspender target={id} />
1229+
</React.Suspense>
1230+
</Contexts>,
1231+
),
1232+
false,
1233+
);
1234+
expect(inspectedElement.props).toMatchInlineSnapshot(`
1235+
Object {
1236+
"data": Object {
1237+
"a": undefined,
1238+
"b": Infinity,
1239+
"c": NaN,
1240+
"d": "normal",
1241+
},
1242+
}
1243+
`);
1244+
1245+
done();
1246+
});
1247+
11711248
it('should not dehydrate nested values until explicitly requested', async done => {
11721249
const Example = () => {
11731250
const [state] = React.useState({

packages/react-devtools-shared/src/__tests__/legacy/inspectElement-test.js

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -588,6 +588,66 @@ describe('InspectedElementContext', () => {
588588
done();
589589
});
590590

591+
it('should allow component prop value and value`s prototype has same name params.', async done => {
592+
const testData = Object.create(
593+
{
594+
a: undefined,
595+
b: Infinity,
596+
c: NaN,
597+
d: 'normal',
598+
},
599+
{
600+
a: {
601+
value: undefined,
602+
writable: true,
603+
enumerable: true,
604+
configurable: true,
605+
},
606+
b: {
607+
value: Infinity,
608+
writable: true,
609+
enumerable: true,
610+
configurable: true,
611+
},
612+
c: {
613+
value: NaN,
614+
writable: true,
615+
enumerable: true,
616+
configurable: true,
617+
},
618+
d: {
619+
value: 'normal',
620+
writable: true,
621+
enumerable: true,
622+
configurable: true,
623+
},
624+
},
625+
);
626+
627+
const Example = ({data}) => null;
628+
act(() =>
629+
ReactDOM.render(
630+
<Example data={testData} />,
631+
document.createElement('div'),
632+
),
633+
);
634+
635+
const id = ((store.getElementIDAtIndex(0): any): number);
636+
const inspectedElement = await read(id);
637+
638+
expect(inspectedElement.props).toMatchInlineSnapshot(`
639+
Object {
640+
"data": Object {
641+
"a": undefined,
642+
"b": Infinity,
643+
"c": NaN,
644+
"d": "normal",
645+
},
646+
}
647+
`);
648+
done();
649+
});
650+
591651
it('should not dehydrate nested values until explicitly requested', async done => {
592652
const Example = () => null;
593653

packages/react-devtools-shared/src/hydration.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,9 @@ export function hydrate(
383383

384384
const value = parent[last];
385385

386-
if (value.type === 'infinity') {
386+
if (!value) {
387+
return;
388+
} else if (value.type === 'infinity') {
387389
parent[last] = Infinity;
388390
} else if (value.type === 'nan') {
389391
parent[last] = NaN;

packages/react-devtools-shared/src/utils.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,8 @@ export function alphaSortKeys(
7070

7171
export function getAllEnumerableKeys(
7272
obj: Object,
73-
): Array<string | number | Symbol> {
74-
const keys = [];
73+
): Set<string | number | Symbol> {
74+
const keys = new Set();
7575
let current = obj;
7676
while (current != null) {
7777
const currentKeys = [
@@ -82,7 +82,7 @@ export function getAllEnumerableKeys(
8282
currentKeys.forEach(key => {
8383
// $FlowFixMe: key can be a Symbol https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptor
8484
if (descriptors[key].enumerable) {
85-
keys.push(key);
85+
keys.add(key);
8686
}
8787
});
8888
current = Object.getPrototypeOf(current);
@@ -767,7 +767,7 @@ export function formatDataForPreview(
767767
return data.toString();
768768
case 'object':
769769
if (showFormattedValue) {
770-
const keys = getAllEnumerableKeys(data).sort(alphaSortKeys);
770+
const keys = Array.from(getAllEnumerableKeys(data)).sort(alphaSortKeys);
771771
772772
let formatted = '';
773773
for (let i = 0; i < keys.length; i++) {

0 commit comments

Comments
 (0)