diff --git a/packages/react-devtools-shared/src/__tests__/__snapshots__/store-test.js.snap b/packages/react-devtools-shared/src/__tests__/__snapshots__/store-test.js.snap index bbd434be6fd21..43a7658fa79b8 100644 --- a/packages/react-devtools-shared/src/__tests__/__snapshots__/store-test.js.snap +++ b/packages/react-devtools-shared/src/__tests__/__snapshots__/store-test.js.snap @@ -607,3 +607,8 @@ exports[`Store should properly handle a root with no visible nodes: 1: mount 1`] `; exports[`Store should properly handle a root with no visible nodes: 2: add host nodes 1`] = `[root]`; + +exports[`Store should properly serialize non-string key values: 1: mount 1`] = ` +[root] + +`; diff --git a/packages/react-devtools-shared/src/__tests__/store-test.js b/packages/react-devtools-shared/src/__tests__/store-test.js index bc8885a2a582f..6525e94427c65 100644 --- a/packages/react-devtools-shared/src/__tests__/store-test.js +++ b/packages/react-devtools-shared/src/__tests__/store-test.js @@ -837,4 +837,15 @@ describe('Store', () => { act(() => ReactDOM.unmountComponentAtNode(containerB)); expect(store.supportsProfiling).toBe(false); }); + + it('should properly serialize non-string key values', () => { + const Child = () => null; + + // Bypass React element's automatic stringifying of keys intentionally. + // This is pretty hacky. + const fauxElement = Object.assign({}, , {key: 123}); + + act(() => ReactDOM.render([fauxElement], document.createElement('div'))); + expect(store).toMatchSnapshot('1: mount'); + }); }); diff --git a/packages/react-devtools-shared/src/backend/renderer.js b/packages/react-devtools-shared/src/backend/renderer.js index be993282a946e..287ec898e3f87 100644 --- a/packages/react-devtools-shared/src/backend/renderer.js +++ b/packages/react-devtools-shared/src/backend/renderer.js @@ -1157,7 +1157,12 @@ export function attach( : 0; let displayNameStringID = getStringID(displayName); - let keyStringID = getStringID(key); + + // This check is a guard to handle a React element that has been modified + // in such a way as to bypass the default stringification of the "key" property. + let keyString = key === null ? null : '' + key; + let keyStringID = getStringID(keyString); + pushOperation(TREE_OPERATION_ADD); pushOperation(id); pushOperation(elementType);