When trying to .find a memoized function component within a mounted tree and .debug it, returns an empty string.
This is regarding the new React.memo feature. When I simply remove the React.memo wrapper from the component, then it is found and its contents printed to the console on .debug. With the wrapper, it appears the component cannot be found.
Should output the component.
Windows 10, GitBash, Jest
| library | version
| ------------------- | -------
| enzyme | 3.9.0
| react | 16.8.3
| react-dom | 16.8
| react-test-renderer | 16.8.4
| adapter (below) | 1.10.0
@papiro can you provide repro code? Specifically, your component, your test code, and wrapper.debug() on the root wrapper?
Phew! That sure would be a lot of code. Lots of components involved, along with the app-environment stubbed out via test-helper HOCs and the lot. I'll try to shuck off what's not needed to reproduce.
I have the same issue, here is a repro:
https://github.com/mliq/enzyme-memo-bug-repro
@ljharb
wrapper.debug() on component without React.memo HOC:
<Button className="mockClass">
<button className="mockClass">
mockContent
</button>
</Button>
wrapper.debug() on component with React.memo HOC:
<Button className="mockClass" />
I'm running into a some sort of similar issue with enzyme-adapter-react-16 1.11.2
Using the constructor to find children won't work but using the display name will work
Here's an example:
// Child.js
import React, { Fragment, memo } from 'react';
function Child() {
return <Fragment>Child</Fragment>;
}
export default memo(Child);
// Parent.js
import React, { memo } from 'react';
import Child from './Child';
function Parent() {
return (
<div>
<Child />
<Child />
</div>
);
};
export default memo(Parent);
import React from 'react';
import { mount } from 'enzyme';
import Parent from './Parent';
import Child from './Child';
const parent = mount(<Parent />);
console.log(parent.debug());
// Returns the right nodes
// <Parent>
// <Child />
// <Child />
// </Parent>
console.log(parent.find(Child).debug());
// Returns nothing
console.log(parent.find('Child').debug());
// Return the right nodes
// <Child />
// <Child />
Encountered the same issue today. React.memo will also not appear in the component tree from debug(): https://codesandbox.io/s/94v1m6p21o
I'll confirm whether it should appear in the debug tree or not; either way, finding by constructor should definitely work.
Affects my code too, can't add React.memo to my functional components because tests fail to find wrapped component children.
When I wrap with memo, I get a shape that looks like this
{ '$$typeof': Symbol(react.memo),
type:
{ [Function: Foo]
displayName: 'Foo',
defaultProps: { theme: {} } },
compare: null }
so in my jest test, i can get the inner component by referencing the type key
import MemoizedFoo from './Foo'
const Foo = MemoizedFoo.type
describe() { it() { shallow(Foo) ...etc } }
This is great for shallow unit tests.
If i was mounting a parent component and looking for children to be present, you could do something like this:
wrapper = mount(Layout)
wrapper.find('Memo(Foo)')
Setting the display name property on the memoized component solved the problem for me.
const TextBase = (props) => {...};
export const Text = React.memo(TextBase);
Text.displayName = 'Text';
I have a similar issue when using non-default export, wich not been memoized.
// Foo.tsx
export const Foo(props) {...};
export default memo(Foo);
// Foo.tests.tsx
import { Foo } from "./Foo"; // should be default import, but no 馃槙
const wrapper = mount(<FooWrapper />);
wrapper.find(Foo)
So I just changed import to use default exported memoized component and the issue has gone.
react-scripts: 3.3.0
enzyme: 3.1.0
jest-enzyme: 7.1.2
Most helpful comment
When I wrap with memo, I get a shape that looks like this
so in my jest test, i can get the inner component by referencing the type key
This is great for shallow unit tests.
If i was mounting a parent component and looking for children to be present, you could do something like this: