Skip to content

Commit 6d4038f

Browse files
rodrigoprtrueadm
authored andcommitted
[ShallowRenderer] Queue/rerender on dispatched action after render component with hooks (#14802)
* [shallow-renderer] Rerender on dispatched action out of render
1 parent fa6205d commit 6d4038f

File tree

2 files changed

+39
-3
lines changed

2 files changed

+39
-3
lines changed

packages/react-test-renderer/src/ReactShallowRenderer.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ class ReactShallowRenderer {
384384
'an infinite loop.',
385385
);
386386

387-
if (componentIdentity === this._currentlyRenderingComponent) {
387+
if (componentIdentity === this._previousComponentIdentity) {
388388
// This is a render phase update. Stash it in a lazily-created map of
389389
// queue -> linked list of updates. After this render pass, we'll restart
390390
// and apply the stashed updates on top of the work-in-progress hook.
@@ -408,10 +408,13 @@ class ReactShallowRenderer {
408408
}
409409
lastRenderPhaseUpdate.next = update;
410410
}
411+
412+
if (!this._rendering) {
413+
this.render(this._element, this._context);
414+
}
411415
} else {
412416
// This means an update has happened after the function component has
413-
// returned. On the server this is a no-op. In React Fiber, the update
414-
// would be scheduled for a future render.
417+
// returned from a different component.
415418
}
416419
}
417420

packages/react-test-renderer/src/__tests__/ReactShallowRendererHooks-test.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,39 @@ describe('ReactShallowRenderer with hooks', () => {
9090
);
9191
});
9292

93+
it('should work with updating a value from useState outside the render', () => {
94+
function SomeComponent({defaultName}) {
95+
const [name, updateName] = React.useState(defaultName);
96+
97+
return (
98+
<div onClick={() => updateName('Dan')}>
99+
<p>
100+
Your name is: <span>{name}</span>
101+
</p>
102+
</div>
103+
);
104+
}
105+
106+
const shallowRenderer = createRenderer();
107+
const element = <SomeComponent defaultName={'Dominic'} />;
108+
const result = shallowRenderer.render(element);
109+
110+
expect(result.props.children).toEqual(
111+
<p>
112+
Your name is: <span>Dominic</span>
113+
</p>,
114+
);
115+
116+
result.props.onClick();
117+
const updated = shallowRenderer.render(element);
118+
119+
expect(updated.props.children).toEqual(
120+
<p>
121+
Your name is: <span>Dan</span>
122+
</p>,
123+
);
124+
});
125+
93126
it('should work with useReducer', () => {
94127
function reducer(state, action) {
95128
switch (action.type) {

0 commit comments

Comments
 (0)