question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

wrapper.find(Component).instance().setState(STATE) sets state, doesn't update render

See original GitHub issue

Current behavior

Setting a wrapped components instance state does show that it has updated the state when observed, but doesn’t update the render when observed

wrapper = mount(
          <Router>
            <IntlProvider locale="en">
              <ComponentExample
                userStore={userStore}
                lenderStore={lenderStore}
                history={history}
                location={history.location}
                match={match}
              />
            </IntlProvider>
          </Router>
        );

Test

wrapper
      .find(ComponentExample)
      .instance()
      .setState(TEST_STATE);
    expect(
      wrapper
        .find(ComponentExample)
        .instance()
        .state
    ).toEqual(TEST_STATE);

Result

PASS

component snippet

public state = {
     loaded:false
}
//other stuff like async componentDidMount, clickHandlers, etc.

public render(){
  const {
    loaded,
    //other state not mentioned here
  } = state;
  return (
    <div className='container'>
      {loaded &&
        (
          <div className='pageHeader'>
            {/* other children */}
          </div>
        )}
      <span>Loading</span>
    </div>
  )
}

TEST 2:

 wrapper
      .find(ComponentExample)
      .instance()
      .setState(TEST_STATE);
    expect(
      wrapper
        .find(ComponentExample)
        .instance()
        .state
    ).toEqual(TEST_STATE);
    wrapper.update();
    expect(
      wrapper
        .find('.pageHeader')
        .isEmptyRender()
    ).toEqual(false)
    expect(
      wrapper
        .find('.pageHeader')
    ).toHaveLength(1)

RESULT

FAIL: ReactWrapper::getNode() can only be called when wrapping one node
FAIL: Expected Length 1, Received Length 0

Expected behavior

TEST 2:

 wrapper
      .find(ComponentExample)
      .instance()
      .setState(TEST_STATE);
    expect(
      wrapper
        .find(ComponentExample)
        .instance()
        .state
    ).toEqual(TEST_STATE);
    wrapper.update();
    expect(
      wrapper
        .find('.pageHeader')
        .isEmptyRender()
    ).toEqual(false)

RESULT

PASS

Your environment

Windows 10

API

  • shallow
  • mount
  • render

Version

library version
enzyme 3.9.0
react 16.4.1
react-dom 16.4.1
react-test-renderer 16.8.6
adapter (below) 1.11.2

Adapter

  • enzyme-adapter-react-16
  • enzyme-adapter-react-16.3
  • enzyme-adapter-react-16.2
  • enzyme-adapter-react-16.1
  • enzyme-adapter-react-15
  • enzyme-adapter-react-15.4
  • enzyme-adapter-react-14
  • enzyme-adapter-react-13
  • enzyme-adapter-react-helper
  • others ( )

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:17 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
GeorgeWLcommented, Apr 13, 2019

Thank you. I wasn’t certain of the cause you see.

0reactions
ljharbcommented, Apr 13, 2019

@GeorgeWL specifically, your componentDidMount is an async function, which returns a promise. You’d have to get access to this promise, and await it in your test, and wrapper.update() after that, to be able to assert on the updated state.

One alternative is to explicitly wrapper.setState({ loaded: true }) rather than relying on cDM to set it.

Either way, this is due to the nature of your component, and not something enzyme-related, so I’m going to close.

Read more comments on GitHub >

github_iconTop Results From Across the Web

setState(nextState[, callback]) · Enzyme - GitHub Pages
A method to invoke setState() on the root component instance, similar to how you might in the methods of the component, and re-renders....
Read more >
In enzyme cannot update state using instance().state and ...
setState() works, but using instance() and then update() does not. Why does update() not re-render my component properly? reactjs · enzyme.
Read more >
React.Component
You may call setState() immediately in componentDidMount() . It will trigger an extra rendering, but it will happen before the browser updates the...
Read more >
setState(state) => Self - Enzyme - UNPKG
A method to invoke setState() on the root component instance similar to how you might in the definition of the component, and re-renders....
Read more >
How to Test React Components: the Complete Guide
So will using wrapper.setState() . So we have passing tests with a non functional app. I dont know about you but this doesnt...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found