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

testing of setState call fails when compound component has few child components #1831

Closed
mgenov opened this issue Sep 21, 2018 · 3 comments
Closed

Comments

@mgenov
Copy link

mgenov commented Sep 21, 2018

Describe the bug
Test fails with strange setState error when multiple childs are rendered and callback is passed to each of them. The strange thing is that setState is called from the production code.

Method “setState” is only meant to be run on a single node. 2 found instead.

      79 |       return React.Children.map(this.props.children, child => {
      80 |         return React.cloneElement(child, {
    > 81 |           onPress: () => this.setState({ name: '::any name::' })
         |                                                       ^
      82 |         })
      83 |       })
      84 |     }

To Reproduce

  class MyComponent extends React.Component {
    render() {
      return React.Children.map(this.props.children, child => {
        return React.cloneElement(child, {
          onPress: () => this.setState({ name: '::any name::' })
        })
      })
    }
  }

  class MyChildComponent extends React.Component {
    render() {
      return <Text>Hello!</Text>
    }
  }

// Test
 const wrapper = shallow(
      <MyComponent>
        <MyChildComponent />
        <MyChildComponent />
      </MyComponent>
    )
    wrapper
      .find(MyChildComponent)
      .first()
      .props()
      .onPress()

    expect(wrapper.state()).toEqual({ name: '::any name::' })

Expected behavior
Test to pass

Desktop (please complete the following information):

  • OS: macOS Sierra
  • Jest Version 23.6.0
  • Enzyme 3.6.0
  • react-native 0.57
@mgenov mgenov changed the title testing of compound component with multiple child fails testing of setState call fails when compound component has few child components Sep 21, 2018
@ljharb
Copy link
Member

ljharb commented Sep 21, 2018

What's the output of wrapper.find(MyChildComponent).first().props().onPress.toString())?

What happens if you add a wrapper.update() before trying to check the state?

@mgenov
Copy link
Author

mgenov commented Sep 21, 2018

What's the output of wrapper.find(MyChildComponent).first().props().onPress.toString())?

function onPress() {return _this.setState({ name: '::any name::' });}

What happens if you add a wrapper.update() before trying to check the state?
Actually the test doesn't fail in the expectation, as it fails when onPress callback is called.

I've tried and with update but the error message is same as code doesn't get to this point at all.

it('bad case', () => {
    const wrapper = shallow(
      <MyComponent>
        <MyChildComponent />
        <MyChildComponent />
      </MyComponent>
    )

    console.log(
      wrapper
        .find(MyChildComponent)
        .first()
        .props()
        .onPress.toString()
    )

    wrapper
      .find(MyChildComponent)
      .first()
      .props()
      .onPress()

    wrapper.update()

    expect(wrapper.state()).toEqual({ name: '::any name::' })
  })

Output:

● (Tabs) Component › bad case

    Method “setState” is only meant to be run on a single node. 2 found instead.

      79 |       return React.Children.map(this.props.children, child => {
      80 |         return React.cloneElement(child, {
    > 81 |           onPress: () => this.setState({ name: '::any name::' })
         |                                                       ^
      82 |         })
      83 |       })
      84 |     }

@ljharb
Copy link
Member

ljharb commented Sep 21, 2018

ahhh this is because enzyme does not yet support components that return non-nodes - ie, an array. If you wrap the React.Children.map in a React.Fragment everything will work.

See #1149; closing this one in favor of that.

@ljharb ljharb closed this as completed Sep 21, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants