@samitouri / QOS-React-2 / commits / 01be61c12f

DevTools can inspect Proxies that return broken iterator functions (#21660)

Brian Vaughn committed Jun 11, 2021 at 10:15 UTC 01be61c12f4361dc9e4c4f4157bffbeb0e57b064
2 files changed +47 -3
packages/react-devtools-shared/src/__tests__/inspectedElement-test.js
+40
@@ -1813,6 +1813,46 @@ describe('InspectedElement', () => {
1813 `);
1814 });
1815
1816 + // See github.com/facebook/react/issues/21654
1817 + it('should support Proxies that dont return an iterator', async () => {
1818 + const Example = () => null;
1819 + const proxy = new Proxy(
1820 + {},
1821 + {
1822 + get: (target, prop, receiver) => {
1823 + target[prop] = value => {};
1824 + return target[prop];
1825 + },
1826 + },
1827 + );
1828 +
1829 + const container = document.createElement('div');
1830 + await utils.actAsync(() =>
1831 + ReactDOM.render(<Example proxy={proxy} />, container),
1832 + );
1833 +
1834 + const inspectedElement = await inspectElementAtIndex(0);
1835 +
1836 + expect(inspectedElement.props).toMatchInlineSnapshot(`
1837 + Object {
1838 + "proxy": Object {
1839 + "$$typeof": Dehydrated {
1840 + "preview_short": ƒ () {},
1841 + "preview_long": ƒ () {},
1842 + },
1843 + "Symbol(Symbol.iterator)": Dehydrated {
1844 + "preview_short": ƒ () {},
1845 + "preview_long": ƒ () {},
1846 + },
1847 + "constructor": Dehydrated {
1848 + "preview_short": ƒ () {},
1849 + "preview_long": ƒ () {},
1850 + },
1851 + },
1852 + }
1853 + `);
1854 + });
1855 +
1856 describe('$r', () => {
1857 it('should support function components', async () => {
1858 const Example = () => {
packages/react-devtools-shared/src/utils.js
+7 -3
@@ -540,9 +540,13 @@ export function getDataType(data: Object): DataType {
540 // but this seems kind of awkward and expensive.
541 return 'array_buffer';
542 } else if (typeof data[Symbol.iterator] === 'function') {
543 - return data[Symbol.iterator]() === data
544 - ? 'opaque_iterator'
545 - : 'iterator';
543 + const iterator = data[Symbol.iterator]();
544 + if (!iterator) {
545 + // Proxies might break assumptoins about iterators.
546 + // See github.com/facebook/react/issues/21654
547 + } else {
548 + return iterator === data ? 'opaque_iterator' : 'iterator';
549 + }
550 } else if (data.constructor && data.constructor.name === 'RegExp') {
551 return 'regexp';
552 } else {