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

Calling setProps() doesn't change props of children anymore #1221

Closed
mattp94 opened this issue Oct 3, 2017 · 15 comments
Closed

Calling setProps() doesn't change props of children anymore #1221

mattp94 opened this issue Oct 3, 2017 · 15 comments

Comments

@mattp94
Copy link

mattp94 commented Oct 3, 2017

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.

@marchaos
Copy link

marchaos commented Oct 5, 2017

Same issue for me. Seems similar to #1229

@Fetz
Copy link

Fetz commented Oct 6, 2017

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

@Kepro
Copy link

Kepro commented Oct 7, 2017

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
Copy link
Member

ljharb commented Oct 7, 2017

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

@Kepro
Copy link

Kepro commented Oct 7, 2017

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

@ljharb
Copy link
Member

ljharb commented Oct 8, 2017

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

@Fetz
Copy link

Fetz commented Oct 9, 2017

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

@ljharb
Copy link
Member

ljharb commented Oct 9, 2017

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

@rsimsek
Copy link

rsimsek commented Feb 20, 2018

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?

@juliosampaio
Copy link

Same situation here :/

@Kepro
Copy link

Kepro commented Feb 28, 2018

can you read comments before you add your comment?

@ANG95
Copy link

ANG95 commented Dec 17, 2020

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();
  });

@victorAttar
Copy link

Working using the solution i find in this comment

But need to use setTimeout every time when made changes is bad.
It is because of the provider? I'm using redux .

beforeEach((done) => {
     wrapper = mount(
        <Provider store={store}>
          <MyDialog />
        </Provider>,
      );
          wrapper.find('form');.simulate('submit', { preventDefault: () => {} });
          setTimeout(() => {
            wrapper.update();
            mydialog = wrapper.find(MyDialog);
            done();
          }, 0);
});

@Kepro
Copy link

Kepro commented Mar 7, 2023

@victorAttar you're commenting on a closed issue from 2017! for help use StackOverflow...

@victorAttar
Copy link

@victorAttar you're commenting on a closed issue from 2017! for help use StackOverflow...

Ended up finding the solution for my problem.

I'm using redux and enzyme, wrapped my componentes to a
Was rendering my componentes only wrapping , causing problem when updating props, because was updating props, not my component props

But i found that enzyme has a wrapper prop, then changed my function from

export function mount(Ui, props) {
  const { Wrapper } = RenderWithRedux(props);
  return MountRender(<Wrapper>{UI}<Wrapper/>);
}

to

export function mount(Ui, props) {
  const { Wrapper } = RenderWithRedux(props);
  return MountRender(Ui, { wrappingComponent: Wrapper });
}

Now wrapper.update() is working!

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

No branches or pull requests

9 participants