-
Notifications
You must be signed in to change notification settings - Fork 47.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add hooks support to ReactShallowRenderer #14567
Conversation
Details of bundled changes.Comparing: 1454a8b...4bc5250 react-test-renderer
Generated by 🚫 dangerJS |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This mostly looks to match up with the existing partial renderer's implementation.
I'm a little concerned about us forgetting to update one if we make changes to the other though.
Seems like this leaks state if you render different component types one after another. Failing test: it('should not leak state when component type changes', () => {
function SomeComponent({defaultName}) {
const [name] = React.useState(defaultName);
return (
<div>
<p>
Your name is: <span>{name}</span>
</p>
</div>
);
}
function SomeOtherComponent({defaultName}) {
const [name] = React.useState(defaultName);
return (
<div>
<p>
Your name is: <span>{name}</span>
</p>
</div>
);
}
const shallowRenderer = createRenderer();
let result = shallowRenderer.render(
<SomeComponent defaultName={'Dominic'} />,
);
expect(result).toEqual(
<div>
<p>
Your name is: <span>Dominic</span>
</p>
</div>,
);
result = shallowRenderer.render(
<SomeOtherComponent defaultName={'Dan'} />,
);
expect(result).toEqual(
<div>
<p>
Your name is: <span>Dan</span>
</p>
</div>,
);
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think overall this looks right but a few things need to change:
- We should only set the dispatcher before rendering, and restore it after. try / finally like we do in SSR.
- Don't leak state between components (Add hooks support to ReactShallowRenderer #14567 (comment)). Rendering a different component type or key should destroy Hook state, like it happens with classes.
- We need to apply changes from Allow useReducer to bail out of rendering by returning previous state #14569 and Don't bother comparing constructor when deps are not provided #14594 for consistency.
For example Allow useReducer to bail out of rendering by returning previous state #14569 (comment). (oops, not this one)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also tag the return value of _createDispatcher
to the typeof Dispatcher
(now that #14599 has landed) 😄
this._createWorkInProgressHook(); | ||
|
||
const nextInputs = | ||
inputs !== undefined && inputs !== null ? inputs : [nextCreate]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can do that, but the reason I didn't was because #14594 didn't make that change to packages/react-dom/src/server/ReactPartialRendererHooks.js.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that's just an omission.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good but let's fix the [nextCreate]
s to be null
s
@gaearon I made that change but it broke things. I don't believe the same logic is meant to be here without changing the types for |
I'm not sure I fully understand what you're saying. What I'm saying is — since #14594, |
FWIW, just as I think the deps argument should be required for them. I should make an issue about it when I'm not half-asleep... 😴 |
@gaearon I've made that change. I was more suggesting there was some confusion over the referenced PR – as it didn't apply the same changed to the partial renderer and I assumed that this was intentional. |
lgtm |
* Add hook support to ReactShallowRenderer
This PR adds React Hooks support to React's test Shallow Renderer. The implementation is mostly based on the ReactDOMServer hooks dispatcher implementation, with a few tweaks to account for the fact that shallow renderer instances do not share state. The ReactDOMServer implementation can be found here:
https://github.com/facebook/react/blob/master/packages/react-dom/src/server/ReactPartialRendererHooks.js#L340-L354
I've added a selection of tests too that confirm the expected behaviour works as intended.