Skip to content

Commit

Permalink
Fixed incompatibility between react-debug-tools and useContext() (#14940
Browse files Browse the repository at this point in the history
)

* Refactor hook ordering check to use DEV-only data structure. This enables us to warn about more cases (e.g. useContext, useDebugValue) withou the need to add any overhead to production bundles.
  • Loading branch information
bvaughn authored Feb 26, 2019
1 parent 0b8efb2 commit 4186952
Show file tree
Hide file tree
Showing 5 changed files with 600 additions and 171 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -427,4 +427,42 @@ 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(1);

let incrementCount;

function Foo(props) {
const context = React.useContext(MyContext);
const [data, setData] = React.useState({count: context});

incrementCount = () => setData(({count}) => ({count: count + 1}));

return <div>count: {data.count}</div>;
}

const renderer = ReactTestRenderer.create(<Foo />);
expect(renderer.toJSON()).toEqual({
type: 'div',
props: {},
children: ['count: ', '1'],
});

act(incrementCount);
expect(renderer.toJSON()).toEqual({
type: 'div',
props: {},
children: ['count: ', '2'],
});

const childFiber = renderer.root._currentFiber();
const tree = ReactDebugTools.inspectHooksOfFiber(childFiber);
expect(tree).toEqual([
{name: 'Context', value: 1, subHooks: []},
{name: 'State', value: {count: 2}, subHooks: []},
]);
});
});
7 changes: 7 additions & 0 deletions packages/react-reconciler/src/ReactFiber.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import type {SideEffectTag} from 'shared/ReactSideEffectTags';
import type {ExpirationTime} from './ReactFiberExpirationTime';
import type {UpdateQueue} from './ReactUpdateQueue';
import type {ContextDependencyList} from './ReactFiberNewContext';
import type {HookType} from './ReactFiberHooks';

import invariant from 'shared/invariant';
import warningWithoutStack from 'shared/warningWithoutStack';
Expand Down Expand Up @@ -204,6 +205,9 @@ export type Fiber = {|
_debugSource?: Source | null,
_debugOwner?: Fiber | null,
_debugIsCurrentlyTiming?: boolean,

// Used to verify that the order of hooks does not change between renders.
_debugHookTypes?: Array<HookType> | null,
|};

let debugCounter;
Expand Down Expand Up @@ -285,6 +289,7 @@ function FiberNode(
this._debugSource = null;
this._debugOwner = null;
this._debugIsCurrentlyTiming = false;
this._debugHookTypes = null;
if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') {
Object.preventExtensions(this);
}
Expand Down Expand Up @@ -370,6 +375,7 @@ export function createWorkInProgress(
workInProgress._debugID = current._debugID;
workInProgress._debugSource = current._debugSource;
workInProgress._debugOwner = current._debugOwner;
workInProgress._debugHookTypes = current._debugHookTypes;
}

workInProgress.alternate = current;
Expand Down Expand Up @@ -723,5 +729,6 @@ export function assignFiberPropertiesInDEV(
target._debugSource = source._debugSource;
target._debugOwner = source._debugOwner;
target._debugIsCurrentlyTiming = source._debugIsCurrentlyTiming;
target._debugHookTypes = source._debugHookTypes;
return target;
}
Loading

0 comments on commit 4186952

Please sign in to comment.