Enzyme: when using React.memo, adding defaultProps changes the component tree

Created on 12 Nov 2020  路  6Comments  路  Source: enzymejs/enzyme

Current behavior

component and component2 are identical: component2 only adds defaultProps, but enzyme treats them differently

// component.js
import PropTypes from 'prop-types';
import React from 'react';
import Child from './child'

const Component = React.memo(function Lazy({type}) {
    return <Child>
        <div>
        </div>
    </Child>;
});

Component.propTypes = {
    type: PropTypes.oneOf(['block', 'inline'])
};

export default Component;

creates tree

    <Memo(Lazy)>
      <Child>
        <div>
          <div />
        </div>
      </Child>
    </Memo(Lazy)>

// component2.js
import PropTypes from 'prop-types';
import React from 'react';
import Child from './child'

const Component = React.memo(function Lazy({type}) {
    return <Child>
        <div>
        </div>
    </Child>;
});

Component.defaultProps = {
    type: 'block'
};

Component.propTypes = {
    type: PropTypes.oneOf(['block', 'inline'])
};

export default Component;

creates tree

    <Lazy type="block">
      <Child>
        <div>
          <div />
        </div>
      </Child>
    </Lazy>

code used to test them:

import React from 'react';
import { configure, mount } from 'enzyme';
import Component from './component';
import Component2 from './component2';
import Adapter from "enzyme-adapter-react-16";

configure({ adapter: new Adapter() });

const comp = mount(<Component />);
const comp2 = mount(<Component2 />)

console.log(comp.debug()); 
console.log(comp2.debug());

API

  • [ ] shallow
  • [x] mount
  • [ ] render

enzyme version: 3.11.0

| library | version
| ------------------- | -------
| enzyme | 3.11.0
| react | 16.14.0
| react-dom | 16.14.0
| react-test-renderer | 16.14.0
| adapter (below) |

Adapter

  • [x] enzyme-adapter-react-16
  • [ ] enzyme-adapter-react-16.3
  • [ ] enzyme-adapter-react-16.2
  • [ ] enzyme-adapter-react-16.1
  • [ ] enzyme-adapter-react-15
  • [ ] enzyme-adapter-react-15.4
  • [ ] enzyme-adapter-react-14
  • [ ] enzyme-adapter-react-13
  • [ ] enzyme-adapter-react-helper
  • [ ] others ( )
mount bug help wanted

Most helpful comment

No, shallow works fine and creates the same tree in the two cases:

<Child>
    <div />
</Child>

All 6 comments

Very interesting. Does it do the same in shallow?

No, shallow works fine and creates the same tree in the two cases:

<Child>
    <div />
</Child>

@UndefinedBehaviour hmm - it actually seems like React itself displays them differently: https://qht9z.csb.app/ if you inspect that in the dev tools, the one with default props is:

LazyC (Memo)
  LazyC
    Child

and the one with defaultProps is:

LazyC (Memo)
  Child

Certainly enzyme should do the same thing on mount vs shallow, and should match React as much as possible, so there's a change to be made here - but it does imply that the result will still change the output based on whether defaultProps is provided.

I've added test cases to cover the existing behavior, with a TODO comment on the line of the test that needs to be changed if fixing this issue requires it.

Hey @ljharb
I have good experience in react and have used enzyme. I will love to help but will need some onboarding .
Please reply with something by which we can connect
I will learn fast.

@rajanlagah We can chat on irc, some of the common slacks, or on this repo's gitter. Happy to have your help.

Was this page helpful?
0 / 5 - 0 ratings