Enzyme: getDerivedStateFromProps not working with setProps

Created on 17 Sep 2018  ·  15Comments  ·  Source: enzymejs/enzyme

Describe the bug
getDerivedStateFromProps don't called when use setProps on shalow component

To Reproduce
Steps to reproduce the behavior:

  1. Use shallow render for component
  2. In getDerivedStateFromProps change state when props change
  3. Use setProps on shallowed component
  4. State not change

Expected behavior
setProps should call getDerivedStateFromProps

Packages

Example
tabs.jsx

export class Tabs extends PureComponent {
  static getDerivedStateFromProps(props, state) {
    const { activeTab } = props;

    if (activeTab !== state.activeTab) {
      return { activeTab };
    }

    return null;
  }

    state = {
      activeTab: 0,
    };
 // ...other code
}

tabs.test.jsx

    wrapper = shallow((
        <Tabs border>
          <Tab label="test">tab content 1</Tab>
          <Tab label="test">tab content 2</Tab>
        </Tabs>
      ));

  test('GDSFP', () => {
   const expectedValue = 'test123';
   wrapper.setProps({ activeTab: expectedValue });

   epxect(wrapper.state().activeTab).toBe(expectedValue);
  });
shallow Need To Reproduce

All 15 comments

Thanks for the repro steps - can you provide the actual _code_ you used when seeing this?

We have explicit tests for this already: https://github.com/airbnb/enzyme/blob/master/packages/enzyme-test-suite/test/ShallowWrapper-spec.jsx#L5004-L5050

are you sure the method isn't being called?

@ljharb Add example to issue. I create new empty component and it's not working

"enzyme": "3.6.0"
"enzyme-adapter-react-16": "1.5.0"
"react": "16.5.1"

import React, { Component } from ‘react’;
import PropTypes from ‘prop-types’;

export class TestMe extends Component {
 static propTypes = {
   activeTab: PropTypes.string,
 };

 state = {
   activeTab: null,
 };


 static getDerivedStateFromProps(props, state) {
   const { activeTab } = props;

   if (activeTab !== state.activeTab) {
     return { activeTab };
   }
   return null;
 }

 render() {
   return <div>{this.state.activeTab}</div>;
 }
}
import { TestMe } from ‘./test-me’;

describe(‘<TestMe />’, () => {
 test(‘should match snapshot’, () => {
   const wrapper = shallow(<TestMe activeTab=“1” />);
   expect(wrapper.state()).toMatchObject({
     activeTab: ‘1’, // FAILS: activeTab is null
   });

   wrapper.setProps({
     activeTab: ‘2’,
   });
   expect(wrapper.state()).toMatchObject({
     activeTab: ‘2’, // FAILS: activeTab is null
   });
 });
});

hmm, the test is passing in my environment.

    it('pass the test', () => {
      class TestMe extends React.Component {
        constructor(props) {
          super(props);
          this.state = {
            activeTab: null,
          };
        }

        static getDerivedStateFromProps(props, state) {
          const { activeTab } = props;
          if (activeTab !== state.activeTab) {
            return { activeTab };
          }
          return null;
        }

        render() {
          return <div>{this.state.activeTab}</div>;
        }
      }

      const wrapper = shallow(<TestMe activeTab="1" />);
      expect(wrapper.state()).to.have.property('activeTab', '1');

      wrapper.setProps({
        activeTab: '2',
      });
      expect(wrapper.state()).to.have.property('activeTab', '2');
    });

Note that enzyme doesn’t have snapshot support; the closest would be debug()

I've experienced the same issue, with getDerivedStateFromProps only being called during the initial shallow render and not during setProps (on latest enzyme and react).

@koba04 What react version you have?

@merrywhether Have you solved this problem?

@merrywhether can you share your versions of react, enzyme, and your react adapter?

@OverVlad [email protected]

@koba04 But for me now working in all my project if I setup latest react with latest enzyme

@OverVlad ok, if you've updated everything and everything is working, then it seems like this is resolved. Happy to reopen it if that's not the case.

Sorry for slow:

"react": "16.5.1",
"enzyme": "3.6.0",
"enzyme-adapter-react-16": "1.5.0",

@merrywhether can you share your component and test code?

Update: the problem was that yarn had pinned my version of react-test-renderer (which was not a direct dependency) to 16.0.0 (via yarn.lock). Forcing that to update seems to have fixed it! 🎉

Was this page helpful?
0 / 5 - 0 ratings