question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Memoized components should forward displayName

See original GitHub issue

Do you want to request a feature or report a bug?

I’d like to report a bug.

What is the current behavior?

First of all, thanks for the great work on fixing https://github.com/facebook/react/issues/14807. However there is still an issue with the current implementation.

React.memo does not forward displayName for tests. In snapshots, components display as <Component /> and string assertions such as .find('MyMemoizedComponent') won’t work.

What is the expected behavior?

React.memo should forward displayName for the test renderer.

Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?

  • React 16.8.5
  • Jest 24.5.0
  • enzyme 3.9.0
  • enzyme-adapter-react-16 1.11.2

N.B. - Potentially related to https://github.com/facebook/react/issues/14319, but this is related to the more recent changes to support memo in the test renderer. Please close if needed, I’m quite new here!

I’d be happy to submit a PR if the issue is not too complex to look into 😄

Issue Analytics

  • State:open
  • Created 4 years ago
  • Reactions:19
  • Comments:16 (7 by maintainers)

github_iconTop GitHub Comments

3reactions
dantmancommented, Aug 16, 2020

Still an issue

3reactions
dantmancommented, Feb 17, 2020

I peeked into the memo source. This is a bit more complex than we thought.

Normally, most HOCs return a component and set a displayName based on displayName || name.

However React.memo does not return a component. It returns an object with $$typeof: REACT_MEMO_TYPE and type.

So there’s no simple “wrap the displayName like other HOCs” because the result is not a component. It’s an informational object that React understands how to process and is closer to the the ReactElement returned by createElement than it is to a component.

I see two potential solutions.

Solution 1: Hack a displayName in

The quick and dirty fix would be to modify memo’s $$typeof: REACT_MEMO_TYPE object to include a displayName property.

This feels like a hack because the memo object is technically not a component and would be equivalent to adding a displayName to Fragment and the other special component types. However this would most likely work pretty universally.

Solution 2: Expect wrappers to handle this

The alternative is to expect that any HOC wrappers will handle memo themselves. So when they see the $$typeof: REACT_MEMO_TYPE they should resolve something similar to memo(${getComponentName(component.type)}).

However if this is the plan I do not think it would be fair to make 3rd party libraries all handle this themselves. memo isn’t the only issue here. forwardRef does something similar, there are a bunch of other special components, and it’s entirely possible there will be a new HOC-like built-in special component in the future. So I think it would be fair in this instance for React to provide an official method of getting the component name that will work with all these special components.

React actually already has this internally. getComponentName.js contains both a getComponentName function that handles name, displayName, memo, Fragment, and more. And even a getWrappedName helper.

For this solution getComponentName and getWrappedName (perhaps rename to wrapComponentName) should be exported officially from somewhere. Either this should be exported from reactor we should have a new package similar toreact-isthat exportsgetComponentNameandgetWrappedName`.

recompose’s getDisplayName will need to be updated to use the official getComponentName – as it’s still used by a lot of people. Likewise other libraries that do the same like @material-ui/utils will need updating.

This is basically #14319.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Avoid anonymous components with `displayName` - Jules Blom
All this hassle is exactly why memoized and forwardReffed components also have a displayName property. We get to have it all by writing...
Read more >
How set displayName to a React stateless component with ...
As for every component in React, React DevTools look for either the name or displayName property of the component itself. You can, therefore ......
Read more >
React.Component
displayName. The displayName string is used in debugging messages. Usually, you don't need to set it explicitly because it's inferred from the name...
Read more >
We memo all the things (2020) - Hacker News
though you would likely want to set displayName before exporting, in reality. ... Functional components and memoize all the things.
Read more >
react/function-component-definition disable - You.com | The Search ...
Exporting an arrow function directly doesn't give the component a displayName , but if you export a regular function the function name will...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found