-
-
Notifications
You must be signed in to change notification settings - Fork 2k
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
ReactWrapper::setState() can only be called on the root #1289
Comments
You can use |
@ljharb Thanks for the reply. I need to use |
Fair. However I'd say a series of shallow-rendering tests, for each component in your tree, would get you more coverage and be easier to write. |
Anyway, I still think that allowing client to call |
There is another use case I've run into. In the case of a single page app, when rendering links from react-router-dom, it's necessary to nest a component inside of a router. This prevents the test from being able to access the state of the component being tested, because ReactWrapper.state() returns the state of the router component at the root. |
Have exactly the same issue with "react-router-dom" as above. Can't test my components due to router wrapper. |
The workaround I've used now is to assign the component instance to a ref and use that to get access to the state.
Then you can read and manipulate state directly:
|
I had a problem with React Router too and solve it by using the dive method. const getComponent = props =>
<MemoryRouter>
<AppHeader {...props} />
</MemoryRouter>
it('should set the state `isMenuOpened` to `true`', () => {
const component = shallow(getComponent()).find(AppHeader).dive()
expect(component.state('isMenuOpened')).toBeFalsy()
component.find(Toggle).simulate('click')
expect(component.state('isMenuOpened')).toBeTruthy()
})
|
Note in the above, you're really testing the AppHeader component without testing the I have a situation where a third party component does some work and then triggers an
If I could set state on |
I'd be happy to review a PR that allows setState to be called on non-root custom component instances in |
Duplicate of #635. |
I found this works to set state of the inner component: const wrapper = mount(
<MuiThemeProvider>
<SubjectListView subjects={subjects}/>
</MuiThemeProvider>);
wrapper.find(SubjectListView).instance().setState({ foo: bar });
wrapper.update(); |
@maxcrystal Great solution. |
@maxcrystal I was starting to wonder why on earth would it be so hard to do something so simple? Great job 👍 👍 |
So how can i set props on non root elements? |
You can wait until the updated version is released, and then update to it. |
It looks like this merge only fixed setting state on child comps though? Or is there another issue for |
ahh sorry, yes, this is only for setState. It doesn't really make sense to arbitrarily set props on a non-root element - the next render would just wipe that out with the props the parent passed. Happy to discuss this in a new issue, though. |
Thank you! Your solution helped me. |
Preface
I had went through #814 and #361 , but I still don't get the answer I want.
Explanation
I know you may say that in practice you should only test a child component in isolation, but I'm in a situation where the child component cannot be rendered without the parent component.
For example, because I'm using React Material-UI, I got to mount the element-to-be-tested inside a theme provider, if not error will be thrown during mounting :
Problem
I need to set the state of
SubjectListView
but then I got thisReactWrapper::setState() can only be called on the root
error.Conclusion
I really hope I can call
setState()
on child element, if not I have to wrap all my components with a<MuiThemeProvider>
which is obviously not a good thing.The text was updated successfully, but these errors were encountered: