From aaf7542afa1e76766410c3ba8f0620a22828437f Mon Sep 17 00:00:00 2001 From: eps1lon Date: Sun, 1 Jan 2023 19:41:30 +0100 Subject: [PATCH] devtools: Use context displayName for context hook name --- .../react-debug-tools/src/ReactDebugHooks.js | 11 ++-- .../src/__tests__/inspectedElement-test.js | 55 +++++++++++++++++++ 2 files changed, 61 insertions(+), 5 deletions(-) diff --git a/packages/react-debug-tools/src/ReactDebugHooks.js b/packages/react-debug-tools/src/ReactDebugHooks.js index 5971c38a97afe..4a1dfa589dd0e 100644 --- a/packages/react-debug-tools/src/ReactDebugHooks.js +++ b/packages/react-debug-tools/src/ReactDebugHooks.js @@ -34,12 +34,12 @@ type CurrentDispatcherRef = typeof ReactSharedInternals.ReactCurrentDispatcher; // Used to track hooks called during a render -type HookLogEntry = { +type HookLogEntry = {| + displayName?: ?string, primitive: string, stackError: Error, value: mixed, - ... -}; +|}; let hookLog: Array = []; @@ -108,6 +108,7 @@ function readContext(context: ReactContext): T { function useContext(context: ReactContext): T { hookLog.push({ + displayName: context.displayName, primitive: 'Context', stackError: new Error(), value: context._currentValue, @@ -582,7 +583,7 @@ function buildTree( } prevStack = stack; } - const {primitive} = hook; + const {displayName, primitive} = hook; // For now, the "id" of stateful hooks is just the stateful hook index. // Custom hooks have no ids, nor do non-stateful native hooks (e.g. Context, DebugValue). @@ -596,7 +597,7 @@ function buildTree( const levelChild: HooksNode = { id, isStateEditable, - name: primitive, + name: displayName || primitive, value: hook.value, subHooks: [], }; diff --git a/packages/react-devtools-shared/src/__tests__/inspectedElement-test.js b/packages/react-devtools-shared/src/__tests__/inspectedElement-test.js index db248a98ca7f2..6ab918537eeb9 100644 --- a/packages/react-devtools-shared/src/__tests__/inspectedElement-test.js +++ b/packages/react-devtools-shared/src/__tests__/inspectedElement-test.js @@ -1696,6 +1696,61 @@ describe('InspectedElement', () => { `); }); + it('should use the displayName of the Context when naming the useContext hook', async () => { + const NamedContext = React.createContext(0); + NamedContext.displayName = 'NamedContext'; + const AnonymousContext = React.createContext(1); + const Example = () => { + React.useContext(NamedContext); + React.useContext(AnonymousContext); + return null; + }; + + const container = document.createElement('div'); + await utils.actAsync(() => legacyRender(, container)); + + const inspectedElement = await inspectElementAtIndex(0); + expect(inspectedElement).toMatchInlineSnapshot(` + Object { + "context": null, + "events": undefined, + "hooks": Array [ + Object { + "hookSource": Object { + "columnNumber": "removed by Jest serializer", + "fileName": "react-devtools-shared/src/__tests__/inspectedElement-test.js", + "functionName": "Example", + "lineNumber": "removed by Jest serializer", + }, + "id": null, + "isStateEditable": false, + "name": "NamedContext", + "subHooks": Array [], + "value": 0, + }, + Object { + "hookSource": Object { + "columnNumber": "removed by Jest serializer", + "fileName": "react-devtools-shared/src/__tests__/inspectedElement-test.js", + "functionName": "Example", + "lineNumber": "removed by Jest serializer", + }, + "id": null, + "isStateEditable": false, + "name": "Context", + "subHooks": Array [], + "value": 1, + }, + ], + "id": 2, + "owners": null, + "props": Object {}, + "rootType": "render()", + "state": null, + } + `); + }); + it('should enable inspected values to be stored as global variables', async () => { const Example = () => null;