Skip to content

Commit

Permalink
fix[devtools/useTransition]: don't check for dispatch property when d…
Browse files Browse the repository at this point in the history
…etermining if hook is stateful (#27365)

#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?
  • Loading branch information
hoxyq committed Sep 21, 2023
1 parent 68ac6db commit 56b1447
Showing 1 changed file with 8 additions and 10 deletions.
18 changes: 8 additions & 10 deletions packages/react-devtools-shared/src/backend/renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -1419,22 +1419,20 @@ export function attach(

const boundHasOwnProperty = hasOwnProperty.bind(queue);

// Detect the shape of useState() or useReducer()
// Detect the shape of useState() / useReducer() / useTransition()
// using the attributes that are unique to these hooks
// but also stable (e.g. not tied to current Lanes implementation)
const isStateOrReducer =
boundHasOwnProperty('pending') &&
boundHasOwnProperty('dispatch') &&
typeof queue.dispatch === 'function';
// We don't check for dispatch property, because useTransition doesn't have it
if (boundHasOwnProperty('pending')) {
return true;
}

// Detect useSyncExternalStore()
const isSyncExternalStore =
return (
boundHasOwnProperty('value') &&
boundHasOwnProperty('getSnapshot') &&
typeof queue.getSnapshot === 'function';

// These are the only types of hooks that can schedule an update.
return isStateOrReducer || isSyncExternalStore;
typeof queue.getSnapshot === 'function'
);
}

function didStatefulHookChange(prev: any, next: any): boolean {
Expand Down

0 comments on commit 56b1447

Please sign in to comment.