@samitouri / QOS-React / commits / b15bf2b2f1

DevTools bugfix for useState() with hasOwnProperty key (#21524)

Brian Vaughn committed May 18, 2021 at 13:43 UTC b15bf2b2f1effb6f760effac9f48c5901622f27b
2 files changed +43 -8
packages/react-devtools-shared/src/__tests__/profilerStore-test.js
+32
@@ -135,4 +135,36 @@ describe('ProfilerStore', () => {
135 });
136 }).toThrow('Cannot modify filter preferences while profiling');
137 });
138 +
139 + it('should not throw if state contains a property hasOwnProperty ', () => {
140 + let setStateCallback;
141 + const ControlledInput = () => {
142 + const [state, setState] = React.useState({hasOwnProperty: true});
143 + setStateCallback = setState;
144 + return state.hasOwnProperty;
145 + };
146 +
147 + const container = document.createElement('div');
148 +
149 + // This element has to be in the <body> for the event system to work.
150 + document.body.appendChild(container);
151 +
152 + // It's important that this test uses legacy sync mode.
153 + // The root API does not trigger this particular failing case.
154 + ReactDOM.render(<ControlledInput />, container);
155 +
156 + utils.act(() => store.profilerStore.startProfiling());
157 + utils.act(() =>
158 + setStateCallback({
159 + hasOwnProperty: false,
160 + }),
161 + );
162 + utils.act(() => store.profilerStore.stopProfiling());
163 +
164 + // Only one commit should have been recorded (in response to the "change" event).
165 + const root = store.roots[0];
166 + const data = store.profilerStore.getDataForRoot(root);
167 + expect(data.commitData).toHaveLength(1);
168 + expect(data.operations).toHaveLength(1);
169 + });
170 });
packages/react-devtools-shared/src/backend/renderer.js
+11 -8
@@ -1221,15 +1221,18 @@ export function attach(
1221 }
1222
1223 function isEffect(memoizedState) {
1224 + if (memoizedState === null || typeof memoizedState !== 'object') {
1225 + return false;
1226 + }
1227 + const {deps} = memoizedState;
1228 + const hasOwnProperty = Object.prototype.hasOwnProperty.bind(memoizedState);
1229 return (
1225 - memoizedState !== null &&
1226 - typeof memoizedState === 'object' &&
1227 - memoizedState.hasOwnProperty('tag') &&
1228 - memoizedState.hasOwnProperty('create') &&
1229 - memoizedState.hasOwnProperty('destroy') &&
1230 - memoizedState.hasOwnProperty('deps') &&
1231 - (memoizedState.deps === null || isArray(memoizedState.deps)) &&
1232 - memoizedState.hasOwnProperty('next')
1230 + hasOwnProperty('create') &&
1231 + hasOwnProperty('destroy') &&
1232 + hasOwnProperty('deps') &&
1233 + hasOwnProperty('next') &&
1234 + hasOwnProperty('tag') &&
1235 + (deps === null || isArray(deps))
1236 );
1237 }
1238