Skip to content

Commit f203060

Browse files
authored
fix: stringifying elements with props containing circular references (#660)
1 parent 25695c3 commit f203060

File tree

2 files changed

+30
-5
lines changed

2 files changed

+30
-5
lines changed

src/formatter/sortObject.js

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* @flow */
22
import * as React from 'react';
33

4-
export default function sortObject(value: any): any {
4+
function safeSortObject(value: any, seen: WeakSet<any>): any {
55
// return non-object value as is
66
if (value === null || typeof value !== 'object') {
77
return value;
@@ -16,9 +16,11 @@ export default function sortObject(value: any): any {
1616
return value;
1717
}
1818

19-
// make a copy of array with each item passed through sortObject()
19+
seen.add(value);
20+
21+
// make a copy of array with each item passed through the sorting algorithm
2022
if (Array.isArray(value)) {
21-
return value.map(sortObject);
23+
return value.map(v => safeSortObject(v, seen));
2224
}
2325

2426
// make a copy of object with key sorted
@@ -28,13 +30,17 @@ export default function sortObject(value: any): any {
2830
if (key === '_owner') {
2931
return result;
3032
}
31-
if (key === 'current') {
33+
if (key === 'current' || seen.has(value[key])) {
3234
// eslint-disable-next-line no-param-reassign
3335
result[key] = '[Circular]';
3436
} else {
3537
// eslint-disable-next-line no-param-reassign
36-
result[key] = sortObject(value[key]);
38+
result[key] = safeSortObject(value[key], seen);
3739
}
3840
return result;
3941
}, {});
4042
}
43+
44+
export default function sortObject(value: any): any {
45+
return safeSortObject(value, new WeakSet());
46+
}

src/index.spec.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1355,4 +1355,23 @@ describe('reactElementToJSXString(ReactElement)', () => {
13551355
]}
13561356
/>`);
13571357
});
1358+
1359+
it('should stringify element with a prop that has circular references', () => {
1360+
const parent = {};
1361+
const child = {};
1362+
parent.child = child;
1363+
child.parent = parent;
1364+
1365+
function Comp() {
1366+
return null;
1367+
}
1368+
1369+
expect(reactElementToJSXString(<Comp prop={parent} />)).toEqual(`<Comp
1370+
prop={{
1371+
child: {
1372+
parent: '[Circular]'
1373+
}
1374+
}}
1375+
/>`);
1376+
});
13581377
});

0 commit comments

Comments
 (0)