Add guard to handle modified React elements with non-string keys (#17164)
Brian Vaughn committed
Oct 29, 2019 at 08:41 UTC
3497ccc14929f6d69d8d48ef41d0b34d1751ce9d
3 files changed
+22
-1
packages/react-devtools-shared/src/__tests__/__snapshots__/store-test.js.snap
+5
@@ -607,3 +607,8 @@ exports[`Store should properly handle a root with no visible nodes: 1: mount 1`]
607
`;
608
609
exports[`Store should properly handle a root with no visible nodes: 2: add host nodes 1`] = `[root]`;
610
+
611
+exports[`Store should properly serialize non-string key values: 1: mount 1`] = `
612
+[root]
613
+ <Child key="123">
614
+`;
packages/react-devtools-shared/src/__tests__/store-test.js
+11
@@ -837,4 +837,15 @@ describe('Store', () => {
837
act(() => ReactDOM.unmountComponentAtNode(containerB));
838
expect(store.supportsProfiling).toBe(false);
839
});
840
+
841
+ it('should properly serialize non-string key values', () => {
842
+ const Child = () => null;
843
+
844
+ // Bypass React element's automatic stringifying of keys intentionally.
845
+ // This is pretty hacky.
846
+ const fauxElement = Object.assign({}, <Child />, {key: 123});
847
+
848
+ act(() => ReactDOM.render([fauxElement], document.createElement('div')));
849
+ expect(store).toMatchSnapshot('1: mount');
850
+ });
851
});
packages/react-devtools-shared/src/backend/renderer.js
+6
-1
@@ -1157,7 +1157,12 @@ export function attach(
1157
: 0;
1158
1159
let displayNameStringID = getStringID(displayName);
1160
- let keyStringID = getStringID(key);
1160
+
1161
+ // This check is a guard to handle a React element that has been modified
1162
+ // in such a way as to bypass the default stringification of the "key" property.
1163
+ let keyString = key === null ? null : '' + key;
1164
+ let keyStringID = getStringID(keyString);
1165
+
1166
pushOperation(TREE_OPERATION_ADD);
1167
pushOperation(id);
1168
pushOperation(elementType);