Skip to content

Commit

Permalink
fix[react-devtools/ReactDebugHooks]: support unstable prefixes in hoo…
Browse files Browse the repository at this point in the history
…ks and useContextWithBailout (#30837)

Related - #30407.

This is experimental-only and FB-only hook. Without these changes,
inspecting an element that is using this hook will throw an error,
because this hook is missing in Dispatcher implementation from React
DevTools, which overrides the original one to build the hook tree.

![Screenshot 2024-08-28 at 18 42
55](https://github.com/user-attachments/assets/e3bccb92-74fb-4e4a-8181-03d13f8512c0)

One nice thing from it is that in case of any potential regressions
related to this experiment, we can quickly triage which implementation
of `useContext` is used by inspecting an element in React DevTools.

Ideally, I should've added some component that is using this hook to
`react-devtools-shell`, so it can be manually tested, but I can't do it
without rewriting the infra for it. This is because this hook is only
available from fb-www builds, and not experimental.
  • Loading branch information
hoxyq authored Aug 30, 2024
1 parent 394e75d commit 8308d2f
Showing 1 changed file with 30 additions and 1 deletion.
31 changes: 30 additions & 1 deletion packages/react-debug-tools/src/ReactDebugHooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import type {
Dependencies,
Fiber,
Dispatcher as DispatcherType,
ContextDependencyWithSelect,
} from 'react-reconciler/src/ReactInternalTypes';
import type {TransitionStatus} from 'react-reconciler/src/ReactFiberConfig';

Expand All @@ -37,7 +38,6 @@ import {
REACT_CONTEXT_TYPE,
} from 'shared/ReactSymbols';
import hasOwnProperty from 'shared/hasOwnProperty';
import type {ContextDependencyWithSelect} from '../../react-reconciler/src/ReactInternalTypes';

type CurrentDispatcherRef = typeof ReactSharedInternals;

Expand Down Expand Up @@ -76,6 +76,13 @@ function getPrimitiveStackCache(): Map<string, Array<any>> {
try {
// Use all hooks here to add them to the hook log.
Dispatcher.useContext(({_currentValue: null}: any));
if (typeof Dispatcher.unstable_useContextWithBailout === 'function') {
// This type check is for Flow only.
Dispatcher.unstable_useContextWithBailout(
({_currentValue: null}: any),
null,
);
}
Dispatcher.useState(null);
Dispatcher.useReducer((s: mixed, a: mixed) => s, null);
Dispatcher.useRef(null);
Expand Down Expand Up @@ -280,6 +287,22 @@ function useContext<T>(context: ReactContext<T>): T {
return value;
}

function unstable_useContextWithBailout<T>(
context: ReactContext<T>,
select: (T => Array<mixed>) | null,
): T {
const value = readContext(context);
hookLog.push({
displayName: context.displayName || null,
primitive: 'ContextWithBailout',
stackError: new Error(),
value: value,
debugInfo: null,
dispatcherHookName: 'ContextWithBailout',
});
return value;
}

function useState<S>(
initialState: (() => S) | S,
): [S, Dispatch<BasicStateAction<S>>] {
Expand Down Expand Up @@ -753,6 +776,7 @@ const Dispatcher: DispatcherType = {
useCacheRefresh,
useCallback,
useContext,
unstable_useContextWithBailout,
useEffect,
useImperativeHandle,
useDebugValue,
Expand Down Expand Up @@ -954,6 +978,11 @@ function parseHookName(functionName: void | string): string {
} else {
startIndex += 1;
}

if (functionName.slice(startIndex).startsWith('unstable_')) {
startIndex += 'unstable_'.length;
}

if (functionName.slice(startIndex, startIndex + 3) === 'use') {
if (functionName.length - startIndex === 3) {
return 'Use';
Expand Down

0 comments on commit 8308d2f

Please sign in to comment.