Skip to content

Commit

Permalink
[ShallowRenderer] Queue/rerender on dispatched action after render co…
Browse files Browse the repository at this point in the history
…mponent with hooks (#14802)

* [shallow-renderer] Rerender on dispatched action out of render
  • Loading branch information
rodrigopr authored and trueadm committed Feb 13, 2019
1 parent fa6205d commit 6d4038f
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 3 deletions.
9 changes: 6 additions & 3 deletions packages/react-test-renderer/src/ReactShallowRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ class ReactShallowRenderer {
'an infinite loop.',
);

if (componentIdentity === this._currentlyRenderingComponent) {
if (componentIdentity === this._previousComponentIdentity) {
// This is a render phase update. Stash it in a lazily-created map of
// queue -> linked list of updates. After this render pass, we'll restart
// and apply the stashed updates on top of the work-in-progress hook.
Expand All @@ -408,10 +408,13 @@ class ReactShallowRenderer {
}
lastRenderPhaseUpdate.next = update;
}

if (!this._rendering) {
this.render(this._element, this._context);
}
} else {
// This means an update has happened after the function component has
// returned. On the server this is a no-op. In React Fiber, the update
// would be scheduled for a future render.
// returned from a different component.
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,39 @@ describe('ReactShallowRenderer with hooks', () => {
);
});

it('should work with updating a value from useState outside the render', () => {
function SomeComponent({defaultName}) {
const [name, updateName] = React.useState(defaultName);

return (
<div onClick={() => updateName('Dan')}>
<p>
Your name is: <span>{name}</span>
</p>
</div>
);
}

const shallowRenderer = createRenderer();
const element = <SomeComponent defaultName={'Dominic'} />;
const result = shallowRenderer.render(element);

expect(result.props.children).toEqual(
<p>
Your name is: <span>Dominic</span>
</p>,
);

result.props.onClick();
const updated = shallowRenderer.render(element);

expect(updated.props.children).toEqual(
<p>
Your name is: <span>Dan</span>
</p>,
);
});

it('should work with useReducer', () => {
function reducer(state, action) {
switch (action.type) {
Expand Down

0 comments on commit 6d4038f

Please sign in to comment.