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

Created on 3 Oct 2017  路  12Comments  路  Source: enzymejs/enzyme

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.

v3 expected difference

Most helpful comment

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?

All 12 comments

Same issue for me. Seems similar to https://github.com/airbnb/enzyme/issues/1229

setProps looks like is not calling componentWillReceiveProps, so probably that is why the props of the children are not updating

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');

````

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

@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...

@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.

@ljharb, then why setProps is not calling of componentWillReceiveProps of root wrapper? Or should is a different issue?

@Fetz that might be a different issue; please file one and include your enzyme and react (and if applicable, enzyme adapter) versions

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?

Same situation here :/

can you read comments before you add your comment?

it("should >>>>>>>>>>>>>>>>>>>", async () => {
    loadWrapper();
    wrapper.update();
    wrapper.setProps({ route: undefined });
    wrapper.update();
    let infoModal = wrapper.find(InfoModal);
    // wrapper.update();
    infoModal = wrapper.find(InfoModal);
    expect(infoModal.props().visible).toBeFalsy();
  });
Was this page helpful?
0 / 5 - 0 ratings

Related issues

potapovDim picture potapovDim  路  3Comments

dschinkel picture dschinkel  路  3Comments

heikkimu picture heikkimu  路  3Comments

SandroMachado picture SandroMachado  路  3Comments

abe903 picture abe903  路  3Comments