Skip to content

Commit 4b7d443

Browse files
eps1lonSebastian Silbermann
authored and
Sebastian Silbermann
committed
devtools: Use context displayName for context hook name
1 parent c1fd2a9 commit 4b7d443

File tree

2 files changed

+79
-2
lines changed

2 files changed

+79
-2
lines changed

packages/react-debug-tools/src/ReactDebugHooks.js

+24-2
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ type CurrentDispatcherRef = typeof ReactSharedInternals.ReactCurrentDispatcher;
3939
// Used to track hooks called during a render
4040

4141
type HookLogEntry = {
42+
displayName: string | null,
4243
primitive: string,
4344
stackError: Error,
4445
value: mixed,
@@ -164,6 +165,7 @@ function use<T>(usable: Usable<T>): T {
164165
case 'fulfilled': {
165166
const fulfilledValue: T = thenable.value;
166167
hookLog.push({
168+
displayName: null,
167169
primitive: 'Promise',
168170
stackError: new Error(),
169171
value: fulfilledValue,
@@ -180,6 +182,7 @@ function use<T>(usable: Usable<T>): T {
180182
// If this was an uncached Promise we have to abandon this attempt
181183
// but we can still emit anything up until this point.
182184
hookLog.push({
185+
displayName: null,
183186
primitive: 'Unresolved',
184187
stackError: new Error(),
185188
value: thenable,
@@ -192,6 +195,7 @@ function use<T>(usable: Usable<T>): T {
192195
const value = readContext(context);
193196

194197
hookLog.push({
198+
displayName: context.displayName || 'Context',
195199
primitive: 'Context (use)',
196200
stackError: new Error(),
197201
value,
@@ -208,6 +212,7 @@ function use<T>(usable: Usable<T>): T {
208212

209213
function useContext<T>(context: ReactContext<T>): T {
210214
hookLog.push({
215+
displayName: context.displayName || null,
211216
primitive: 'Context',
212217
stackError: new Error(),
213218
value: context._currentValue,
@@ -228,6 +233,7 @@ function useState<S>(
228233
initialState()
229234
: initialState;
230235
hookLog.push({
236+
displayName: null,
231237
primitive: 'State',
232238
stackError: new Error(),
233239
value: state,
@@ -249,6 +255,7 @@ function useReducer<S, I, A>(
249255
state = init !== undefined ? init(initialArg) : ((initialArg: any): S);
250256
}
251257
hookLog.push({
258+
displayName: null,
252259
primitive: 'Reducer',
253260
stackError: new Error(),
254261
value: state,
@@ -261,6 +268,7 @@ function useRef<T>(initialValue: T): {current: T} {
261268
const hook = nextHook();
262269
const ref = hook !== null ? hook.memoizedState : {current: initialValue};
263270
hookLog.push({
271+
displayName: null,
264272
primitive: 'Ref',
265273
stackError: new Error(),
266274
value: ref.current,
@@ -272,6 +280,7 @@ function useRef<T>(initialValue: T): {current: T} {
272280
function useCacheRefresh(): () => void {
273281
const hook = nextHook();
274282
hookLog.push({
283+
displayName: null,
275284
primitive: 'CacheRefresh',
276285
stackError: new Error(),
277286
value: hook !== null ? hook.memoizedState : function refresh() {},
@@ -286,6 +295,7 @@ function useLayoutEffect(
286295
): void {
287296
nextHook();
288297
hookLog.push({
298+
displayName: null,
289299
primitive: 'LayoutEffect',
290300
stackError: new Error(),
291301
value: create,
@@ -299,6 +309,7 @@ function useInsertionEffect(
299309
): void {
300310
nextHook();
301311
hookLog.push({
312+
displayName: null,
302313
primitive: 'InsertionEffect',
303314
stackError: new Error(),
304315
value: create,
@@ -312,6 +323,7 @@ function useEffect(
312323
): void {
313324
nextHook();
314325
hookLog.push({
326+
displayName: null,
315327
primitive: 'Effect',
316328
stackError: new Error(),
317329
value: create,
@@ -334,6 +346,7 @@ function useImperativeHandle<T>(
334346
instance = ref.current;
335347
}
336348
hookLog.push({
349+
displayName: null,
337350
primitive: 'ImperativeHandle',
338351
stackError: new Error(),
339352
value: instance,
@@ -343,6 +356,7 @@ function useImperativeHandle<T>(
343356

344357
function useDebugValue(value: any, formatterFn: ?(value: any) => any) {
345358
hookLog.push({
359+
displayName: null,
346360
primitive: 'DebugValue',
347361
stackError: new Error(),
348362
value: typeof formatterFn === 'function' ? formatterFn(value) : value,
@@ -353,6 +367,7 @@ function useDebugValue(value: any, formatterFn: ?(value: any) => any) {
353367
function useCallback<T>(callback: T, inputs: Array<mixed> | void | null): T {
354368
const hook = nextHook();
355369
hookLog.push({
370+
displayName: null,
356371
primitive: 'Callback',
357372
stackError: new Error(),
358373
value: hook !== null ? hook.memoizedState[0] : callback,
@@ -368,6 +383,7 @@ function useMemo<T>(
368383
const hook = nextHook();
369384
const value = hook !== null ? hook.memoizedState[0] : nextCreate();
370385
hookLog.push({
386+
displayName: null,
371387
primitive: 'Memo',
372388
stackError: new Error(),
373389
value,
@@ -388,6 +404,7 @@ function useSyncExternalStore<T>(
388404
nextHook(); // Effect
389405
const value = getSnapshot();
390406
hookLog.push({
407+
displayName: null,
391408
primitive: 'SyncExternalStore',
392409
stackError: new Error(),
393410
value,
@@ -406,6 +423,7 @@ function useTransition(): [
406423
nextHook(); // State
407424
nextHook(); // Callback
408425
hookLog.push({
426+
displayName: null,
409427
primitive: 'Transition',
410428
stackError: new Error(),
411429
value: undefined,
@@ -417,6 +435,7 @@ function useTransition(): [
417435
function useDeferredValue<T>(value: T, initialValue?: T): T {
418436
const hook = nextHook();
419437
hookLog.push({
438+
displayName: null,
420439
primitive: 'DeferredValue',
421440
stackError: new Error(),
422441
value: hook !== null ? hook.memoizedState : value,
@@ -429,6 +448,7 @@ function useId(): string {
429448
const hook = nextHook();
430449
const id = hook !== null ? hook.memoizedState : '';
431450
hookLog.push({
451+
displayName: null,
432452
primitive: 'Id',
433453
stackError: new Error(),
434454
value: id,
@@ -478,6 +498,7 @@ function useOptimistic<S, A>(
478498
state = passthrough;
479499
}
480500
hookLog.push({
501+
displayName: null,
481502
primitive: 'Optimistic',
482503
stackError: new Error(),
483504
value: state,
@@ -500,6 +521,7 @@ function useFormState<S, P>(
500521
state = initialState;
501522
}
502523
hookLog.push({
524+
displayName: null,
503525
primitive: 'FormState',
504526
stackError: new Error(),
505527
value: state,
@@ -773,7 +795,7 @@ function buildTree(
773795
}
774796
prevStack = stack;
775797
}
776-
const {primitive, debugInfo} = hook;
798+
const {displayName, primitive, debugInfo} = hook;
777799

778800
// For now, the "id" of stateful hooks is just the stateful hook index.
779801
// Custom hooks have no ids, nor do non-stateful native hooks (e.g. Context, DebugValue).
@@ -788,7 +810,7 @@ function buildTree(
788810

789811
// For the time being, only State and Reducer hooks support runtime overrides.
790812
const isStateEditable = primitive === 'Reducer' || primitive === 'State';
791-
const name = primitive === 'Context (use)' ? 'Context' : primitive;
813+
const name = displayName || primitive;
792814
const levelChild: HooksNode = {
793815
id,
794816
isStateEditable,

packages/react-devtools-shared/src/__tests__/inspectedElement-test.js

+55
Original file line numberDiff line numberDiff line change
@@ -1731,6 +1731,61 @@ describe('InspectedElement', () => {
17311731
`);
17321732
});
17331733

1734+
it('should use the displayName of the Context when naming the useContext hook', async () => {
1735+
const NamedContext = React.createContext(0);
1736+
NamedContext.displayName = 'NamedContext';
1737+
const AnonymousContext = React.createContext(1);
1738+
const Example = () => {
1739+
React.useContext(NamedContext);
1740+
React.useContext(AnonymousContext);
1741+
return null;
1742+
};
1743+
1744+
const container = document.createElement('div');
1745+
await utils.actAsync(() => legacyRender(<Example />, container));
1746+
1747+
const inspectedElement = await inspectElementAtIndex(0);
1748+
expect(inspectedElement).toMatchInlineSnapshot(`
1749+
Object {
1750+
"context": null,
1751+
"events": undefined,
1752+
"hooks": Array [
1753+
Object {
1754+
"hookSource": Object {
1755+
"columnNumber": "removed by Jest serializer",
1756+
"fileName": "react-devtools-shared/src/__tests__/inspectedElement-test.js",
1757+
"functionName": "Example",
1758+
"lineNumber": "removed by Jest serializer",
1759+
},
1760+
"id": null,
1761+
"isStateEditable": false,
1762+
"name": "NamedContext",
1763+
"subHooks": Array [],
1764+
"value": 0,
1765+
},
1766+
Object {
1767+
"hookSource": Object {
1768+
"columnNumber": "removed by Jest serializer",
1769+
"fileName": "react-devtools-shared/src/__tests__/inspectedElement-test.js",
1770+
"functionName": "Example",
1771+
"lineNumber": "removed by Jest serializer",
1772+
},
1773+
"id": null,
1774+
"isStateEditable": false,
1775+
"name": "Context",
1776+
"subHooks": Array [],
1777+
"value": 1,
1778+
},
1779+
],
1780+
"id": 2,
1781+
"owners": null,
1782+
"props": Object {},
1783+
"rootType": "render()",
1784+
"state": null,
1785+
}
1786+
`);
1787+
});
1788+
17341789
it('should enable inspected values to be stored as global variables', async () => {
17351790
const Example = () => null;
17361791

0 commit comments

Comments
 (0)