enzyme: Calling setProps() doesn't change props of children anymore

I just switched to Enzyme v3 with React v15.6 and I could notice that setProps() doesn’t change props of children anymore. Instead, it only changes props of wrapper:

Config

{
    "enzyme":"^3.1.0",
    "enzyme-adapter-react-15":"^1.0.1",
    "jest":"^21.2.1",
    "react":"^15.6.2",
    "react-dom":"^15.6.2",
    "react-test-renderer":"^15.6.2"
}

Test

import React from 'react'
import Enzyme from 'enzyme'
import Adapter from 'enzyme-adapter-react-15'

Enzyme.configure({ adapter: new Adapter() })

const Child = () => null
const Parent = props => <Child test={props.test} />

it('should update prop test', () => {
    const parent = Enzyme.mount(<Parent test="foo" />)
    const child = parent.find(Child)

    expect(parent.prop('test')).toBe('foo') // true (foo)
    expect(child.prop('test')).toBe('foo') // true (foo)

    parent.setProps({ test: 'bar' })

    expect(parent.prop('test')).toBe('bar') // true (bar)
    expect(child.prop('test')).toBe('bar') // false (foo)
})

The above test works with Enzyme v2.

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 14
  • Comments: 15 (3 by maintainers)

Most upvoted comments

can you read comments before you add your comment?

It is an intended change in v3 to require you to re-find elements if you want changes reflected.

Hi, I have been trying to update children props with calling setProps on the wrapper but that does not do the trick. Is there a way to update it? I have tried by finding the element but that does not work either. Is there an example for that?

@Kepro when you use .find in v2, you get a wrapper that updates automatically when the root wrapper updates. In v3, it’s immutable, so you have to re-find from the root to see changes reflected.

same here, btw HACK! if you find again that child then props will be new… OLD code stop working

    const input = wrapper.find('input[type="text"]');

    expect(input.props().value).toBe('before');
    wrapper.setProps({ value: { test: 'after' } });
    expect(input.props().value).toBe('after');

new code start working…

    const input = wrapper.find('input[type="text"]');

    expect(input.props().value).toBe('before');
    wrapper.setProps({ value: { test: 'after' } });
    const inputAfter = wrapper.find('input[type="text"]');
    expect(inputAfter.props().value).toBe('after');

@ljharb, but why if we have .props() method? that method should return actual props, this will cause duplications in a code… btw there is no information in migrating notes about this…