diff --git a/packages/react-debug-tools/src/ReactDebugHooks.js b/packages/react-debug-tools/src/ReactDebugHooks.js index 2dc1ddb02cac2..03628a6e3bc95 100644 --- a/packages/react-debug-tools/src/ReactDebugHooks.js +++ b/packages/react-debug-tools/src/ReactDebugHooks.js @@ -93,6 +93,10 @@ function useContext( context: ReactContext, observedBits: void | number | boolean, ): T { + if (__DEV__) { + // ReactFiberHooks only adds context to the hooks list in DEV. + nextHook(); + } hookLog.push({ primitive: 'Context', stackError: new Error(), diff --git a/packages/react-debug-tools/src/__tests__/ReactHooksInspectionIntegration-test.js b/packages/react-debug-tools/src/__tests__/ReactHooksInspectionIntegration-test.js index 3c7972aff4df8..4a73f11e41780 100644 --- a/packages/react-debug-tools/src/__tests__/ReactHooksInspectionIntegration-test.js +++ b/packages/react-debug-tools/src/__tests__/ReactHooksInspectionIntegration-test.js @@ -427,4 +427,29 @@ describe('ReactHooksInspectionIntegration', () => { expect(setterCalls[0]).not.toBe(initial); expect(setterCalls[1]).toBe(initial); }); + + // This test case is based on an open source bug report: + // facebookincubator/redux-react-hook/issues/34#issuecomment-466693787 + it('should properly advance the current hook for useContext', () => { + const MyContext = React.createContext(123); + + let hasInitializedState = false; + const initializeStateOnce = () => { + if (hasInitializedState) { + throw Error('State initialization function should only be called once.'); + } + hasInitializedState = true; + return {foo: 'abc'}; + }; + + function Foo(props) { + React.useContext(MyContext); + const [data] = React.useState(initializeStateOnce); + return
foo: {data.foo}
; + } + + const renderer = ReactTestRenderer.create(); + const childFiber = renderer.root._currentFiber(); + ReactDebugTools.inspectHooksOfFiber(childFiber); + }); }); diff --git a/packages/react-reconciler/src/ReactFiberHooks.js b/packages/react-reconciler/src/ReactFiberHooks.js index 702814f9c449d..e312b8ee81df0 100644 --- a/packages/react-reconciler/src/ReactFiberHooks.js +++ b/packages/react-reconciler/src/ReactFiberHooks.js @@ -525,6 +525,7 @@ function mountContext( observedBits: void | number | boolean, ): T { if (__DEV__) { + // If this DEV conditional is ever removed, update ReactDebugHooks useContext too. mountWorkInProgressHook(); } return readContext(context, observedBits); @@ -535,6 +536,7 @@ function updateContext( observedBits: void | number | boolean, ): T { if (__DEV__) { + // If this DEV conditional is ever removed, update ReactDebugHooks useContext too. updateWorkInProgressHook(); } return readContext(context, observedBits);