From 7dfea9656358f425c3a4ce62e26a529e3474f697 Mon Sep 17 00:00:00 2001 From: Sebastian Silbermann Date: Wed, 6 Mar 2024 18:07:46 +0100 Subject: [PATCH] Current behavior for returning incorrect deferred value in debug-tools dispatcher --- .../ReactHooksInspectionIntegration-test.js | 244 ++++++++++++++++++ 1 file changed, 244 insertions(+) diff --git a/packages/react-debug-tools/src/__tests__/ReactHooksInspectionIntegration-test.js b/packages/react-debug-tools/src/__tests__/ReactHooksInspectionIntegration-test.js index 97110f682d572..e741a84063d43 100644 --- a/packages/react-debug-tools/src/__tests__/ReactHooksInspectionIntegration-test.js +++ b/packages/react-debug-tools/src/__tests__/ReactHooksInspectionIntegration-test.js @@ -1206,6 +1206,250 @@ describe('ReactHooksInspectionIntegration', () => { `); }); + it('should return the deferred value', async () => { + let unsuspend; + function Lazy() { + return 'Lazy'; + } + const Suspender = React.lazy( + () => + new Promise(resolve => { + unsuspend = () => resolve({default: Lazy}); + }), + ); + const Context = React.createContext('default'); + let setShow; + function Foo(props) { + const [show, _setShow] = React.useState(false); + const deferredShow = React.useDeferredValue(show); + const isPending = show !== deferredShow; + const contextDisplay = isPending ? React.use(Context) : ''; + React.useMemo(() => 'hello', []); + React.useMemo(() => 'not used', []); + + // Otherwise we capture the version from the react-debug-tools dispatcher. + if (setShow === undefined) { + setShow = _setShow; + } + + return ( + + Context: {contextDisplay}, {isPending ? 'Pending' : 'Nothing Pending'} + {deferredShow ? [', ', ] : null} + + ); + } + const renderer = await act(() => { + return ReactTestRenderer.create( + + + , + {isConcurrent: true}, + ); + }); + let childFiber = renderer.root.findByType(Foo)._currentFiber(); + let tree = ReactDebugTools.inspectHooksOfFiber(childFiber); + expect(renderer).toMatchRenderedOutput('Context: , Nothing Pending'); + expect(normalizeSourceLoc(tree)).toMatchInlineSnapshot(` + [ + { + "debugInfo": null, + "hookSource": { + "columnNumber": 0, + "fileName": "**", + "functionName": "Foo", + "lineNumber": 0, + }, + "id": 0, + "isStateEditable": true, + "name": "State", + "subHooks": [], + "value": false, + }, + { + "debugInfo": null, + "hookSource": { + "columnNumber": 0, + "fileName": "**", + "functionName": "Foo", + "lineNumber": 0, + }, + "id": 1, + "isStateEditable": false, + "name": "DeferredValue", + "subHooks": [], + "value": false, + }, + { + "debugInfo": null, + "hookSource": { + "columnNumber": 0, + "fileName": "**", + "functionName": "Foo", + "lineNumber": 0, + }, + "id": 2, + "isStateEditable": false, + "name": "Memo", + "subHooks": [], + "value": "hello", + }, + { + "debugInfo": null, + "hookSource": { + "columnNumber": 0, + "fileName": "**", + "functionName": "Foo", + "lineNumber": 0, + }, + "id": 3, + "isStateEditable": false, + "name": "Memo", + "subHooks": [], + "value": "not used", + }, + ] + `); + + await act(() => { + setShow(true); + }); + + expect(renderer).toMatchRenderedOutput('Context: provided, Pending'); + childFiber = renderer.root.findByType(Foo)._currentFiber(); + tree = ReactDebugTools.inspectHooksOfFiber(childFiber); + expect(normalizeSourceLoc(tree)).toMatchInlineSnapshot(` + [ + { + "debugInfo": null, + "hookSource": { + "columnNumber": 0, + "fileName": "**", + "functionName": "Foo", + "lineNumber": 0, + }, + "id": 0, + "isStateEditable": true, + "name": "State", + "subHooks": [], + "value": true, + }, + { + "debugInfo": null, + "hookSource": { + "columnNumber": 0, + "fileName": "**", + "functionName": "Foo", + "lineNumber": 0, + }, + "id": 1, + "isStateEditable": false, + "name": "DeferredValue", + "subHooks": [], + "value": false, + }, + { + "debugInfo": null, + "hookSource": { + "columnNumber": 0, + "fileName": "**", + "functionName": "Foo", + "lineNumber": 0, + }, + "id": 2, + "isStateEditable": false, + "name": "Memo", + "subHooks": [], + "value": "hello", + }, + { + "debugInfo": null, + "hookSource": { + "columnNumber": 0, + "fileName": "**", + "functionName": "Foo", + "lineNumber": 0, + }, + "id": 3, + "isStateEditable": false, + "name": "Memo", + "subHooks": [], + "value": "not used", + }, + ] + `); + + await act(() => { + unsuspend(); + }); + + expect(renderer).toMatchRenderedOutput( + 'Context: , Nothing Pending, Lazy', + ); + childFiber = renderer.root.findByType(Foo)._currentFiber(); + tree = ReactDebugTools.inspectHooksOfFiber(childFiber); + expect(normalizeSourceLoc(tree)).toMatchInlineSnapshot(` + [ + { + "debugInfo": null, + "hookSource": { + "columnNumber": 0, + "fileName": "**", + "functionName": "Foo", + "lineNumber": 0, + }, + "id": 0, + "isStateEditable": true, + "name": "State", + "subHooks": [], + "value": true, + }, + { + "debugInfo": null, + "hookSource": { + "columnNumber": 0, + "fileName": "**", + "functionName": "Foo", + "lineNumber": 0, + }, + "id": 1, + "isStateEditable": false, + "name": "DeferredValue", + "subHooks": [], + "value": true, + }, + { + "debugInfo": null, + "hookSource": { + "columnNumber": 0, + "fileName": "**", + "functionName": "Foo", + "lineNumber": 0, + }, + "id": 2, + "isStateEditable": false, + "name": "Memo", + "subHooks": [], + "value": "hello", + }, + { + "debugInfo": null, + "hookSource": { + "columnNumber": 0, + "fileName": "**", + "functionName": "Foo", + "lineNumber": 0, + }, + "id": 3, + "isStateEditable": false, + "name": "Memo", + "subHooks": [], + "value": "not used", + }, + ] + `); + }); + it('should support useId hook', () => { function Foo(props) { const id = React.useId();