@samitouri / QOS-React-2 / commits / 56b14477e9

fix[devtools/useTransition]: don't check for dispatch property when determining if hook is stateful (#27365)

https://github.com/facebook/react/pull/26740 introduced regression: React DevTools doesn't record updates for `useTransition` hook. I can add more details about things on DevTools side, if needed. The root cause is https://github.com/facebook/react/blob/491aec5d6113ce5bae7c10966bc38a4a8fc091a8/packages/react-reconciler/src/ReactFiberHooks.js#L2728-L2730 React DevTools expects dispatch to be present for stateful hooks that can schedule an update - https://github.com/facebook/react/blob/2eed1328478e8c923fcb4e6abf5efbd9e1233402/packages/react-devtools-shared/src/backend/renderer.js#L1422-L1428 With these changes, we still call dispatch in `startTransition`, but also patch `queue` object with it, so that React DevTools can recognise `useTransition` as stateful hook that can schedule update. I am not sure if this is the right approach to fix this, can we distinguish if `startTransition` was called from `useTransition` hook or as a standalone function?

Ruslan Lesiutin committed Sep 21, 2023 at 21:26 UTC 56b14477e902ac076018be2e7bf2ea3092ac9e7d
1 file changed +8 -10
packages/react-devtools-shared/src/backend/renderer.js
+8 -10
@@ -1419,22 +1419,20 @@ export function attach(
1419
1420 const boundHasOwnProperty = hasOwnProperty.bind(queue);
1421
1422 - // Detect the shape of useState() or useReducer()
1422 + // Detect the shape of useState() / useReducer() / useTransition()
1423 // using the attributes that are unique to these hooks
1424 // but also stable (e.g. not tied to current Lanes implementation)
1425 - const isStateOrReducer =
1426 - boundHasOwnProperty('pending') &&
1427 - boundHasOwnProperty('dispatch') &&
1428 - typeof queue.dispatch === 'function';
1425 + // We don't check for dispatch property, because useTransition doesn't have it
1426 + if (boundHasOwnProperty('pending')) {
1427 + return true;
1428 + }
1429
1430 // Detect useSyncExternalStore()
1431 - const isSyncExternalStore =
1431 + return (
1432 boundHasOwnProperty('value') &&
1433 boundHasOwnProperty('getSnapshot') &&
1434 - typeof queue.getSnapshot === 'function';
1435 -
1436 - // These are the only types of hooks that can schedule an update.
1437 - return isStateOrReducer || isSyncExternalStore;
1434 + typeof queue.getSnapshot === 'function'
1435 + );
1436 }
1437
1438 function didStatefulHookChange(prev: any, next: any): boolean {