Skip to content
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

[Fix] shallow: .setState(): stub out setState on non-root code paths as well. #1763

Merged
merged 4 commits into from
Aug 17, 2018

Conversation

ljharb
Copy link
Member

@ljharb ljharb commented Aug 17, 2018

Fixes #1756

cc @koba04

}
}

expect(shallow(<Comp />).debug()).to.equal('');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does setState in componentDidMount invoke componentDidUpdate?

Copy link
Member Author

@ljharb ljharb Aug 17, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it should; cDU is invoked whenever the component updates. no?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In order to be called cDU, we should stub setState so I think we should move calling cDM after the stubbing.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

({ instance } = this[RENDERER].getNode());
}
// Ensure to call componentDidUpdate when instance.setState is called
if (instance && lifecycles.componentDidUpdate.onSetState && !instance[SET_STATE]) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nits: I should have overridden setState only in options.disableLifecycleMethods is false.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'll add a test for that.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually, can you write one? :-D i'm not sure where to put it.

or is this just an optimization?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a05d4cb is the right place. It is unnecessary when options. disableLifecycleMethods is true.

@ljharb
Copy link
Member Author

ljharb commented Aug 17, 2018

Thanks, this looks great. Will merge once tests pass.

@ljharb ljharb merged commit 5a047b3 into master Aug 17, 2018
@ljharb ljharb deleted the fix_shallow_setstate branch August 17, 2018 04:55
ljharb added a commit that referenced this pull request Aug 17, 2018
[Fix] `shallow`: `.setState()`: stub out `setState` on non-root code paths as well.
@monken
Copy link

monken commented Aug 17, 2018

Not sure why, but the 3.4.3 release broke my tests. I receive Error: ShallowWrapper::setState() can only be called on the root errors all over the place.

The relevant test is attached. I was able to figure out that componentDidMount is called twice with the 3.4.3 release, which was not the case before.

  it('<MyComponent />', async () => {
    fetch.mockResponse(JSON.stringify(jsonData));
    const wrapper = shallow(<MyComponent />, { disableLifecycleMethods: true });
    await wrapper.instance().componentDidMount();
    wrapper.update();
    expect(fetch.mock.calls.length).toEqual(1);
    expect(wrapper.find(Table).length).toEqual(1);
  });

@ljharb
Copy link
Member Author

ljharb commented Aug 17, 2018

@monken please file a new issue; commenting on a merged PR isn't going to get anything fixed.

@@ -2142,7 +2142,7 @@ describe('shallow', () => {
expect(wrapper.find('.bar')).to.have.lengthOf(1);
});

it.skip('allows setState inside of componentDidMount', () => {
it('allows setState inside of componentDidMount', () => {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should not allow setState inside of componentDidMount

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why would it not?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
React 16
  
Bugs
Development

Successfully merging this pull request may close these issues.

None yet

4 participants