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

Memoized components should forward displayName #15207

Open
pbondoer opened this issue Mar 25, 2019 · 16 comments
Open

Memoized components should forward displayName #15207

pbondoer opened this issue Mar 25, 2019 · 16 comments

Comments

@pbondoer
Copy link

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 #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 #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 😄

@gaearon
Copy link
Collaborator

gaearon commented Mar 26, 2019

Sure, happy to take a PR.

@LorenzoOpWerk
Copy link

@pbondoer Did you start looking into this already ?

@pbondoer
Copy link
Author

pbondoer commented Apr 1, 2019

@LorenzoOpWerk Yes, just haven't had a lot of free time to finish up.

@eps1lon
Copy link
Collaborator

eps1lon commented Apr 3, 2019

@pbondoer I'm not sure this is an issue with react but rather with enzyme. I don't know how jest serialized enzyme wrappers but I suspect it uses wrapper.debug() at which point this is an issue with enzyme not react.

Find by display name might either be another issue or resolved with enzymejs/enzyme#2081

Though I did submit a PR related to display name behavior with memo components: #15313

@dantman
Copy link
Contributor

dantman commented Apr 12, 2019

I don't think this is a test renderer/enzyme issue.

Astonishingly React.memo in normal usage does not appear to pass on .name or .displayName to the resulting component's .displayName.

https://codesandbox.io/embed/n3532xvxzj

@elie222
Copy link

elie222 commented Nov 19, 2019

Same issue appears when using it with React devtools. Wrapped components show up as Component in the tree.

@stale
Copy link

stale bot commented Feb 17, 2020

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contribution.

@stale stale bot added the Resolution: Stale Automatically closed due to inactivity label Feb 17, 2020
@dantman
Copy link
Contributor

dantman commented Feb 17, 2020

Should not be closed.

@stale stale bot removed the Resolution: Stale Automatically closed due to inactivity label Feb 17, 2020
@dantman
Copy link
Contributor

dantman commented 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.

@stale
Copy link

stale bot commented May 18, 2020

This issue has been automatically marked as stale. If this issue is still affecting you, please leave any comment (for example, "bump"), and we'll keep it open. We are sorry that we haven't been able to prioritize it yet. If you have any new additional information, please include it with your comment!

@stale stale bot added the Resolution: Stale Automatically closed due to inactivity label May 18, 2020
@ljharb
Copy link
Contributor

ljharb commented May 18, 2020

bump

@stale stale bot removed the Resolution: Stale Automatically closed due to inactivity label May 18, 2020
@stale
Copy link

stale bot commented Aug 16, 2020

This issue has been automatically marked as stale. If this issue is still affecting you, please leave any comment (for example, "bump"), and we'll keep it open. We are sorry that we haven't been able to prioritize it yet. If you have any new additional information, please include it with your comment!

@stale stale bot added the Resolution: Stale Automatically closed due to inactivity label Aug 16, 2020
@dantman
Copy link
Contributor

dantman commented Aug 16, 2020

Still an issue

@stale stale bot removed the Resolution: Stale Automatically closed due to inactivity label Aug 16, 2020
@stale
Copy link

stale bot commented Dec 25, 2020

This issue has been automatically marked as stale. If this issue is still affecting you, please leave any comment (for example, "bump"), and we'll keep it open. We are sorry that we haven't been able to prioritize it yet. If you have any new additional information, please include it with your comment!

@stale stale bot added the Resolution: Stale Automatically closed due to inactivity label Dec 25, 2020
@ljharb
Copy link
Contributor

ljharb commented Dec 25, 2020

bump

@stale stale bot removed the Resolution: Stale Automatically closed due to inactivity label Dec 25, 2020
@pbondoer
Copy link
Author

I have a bit of free time these holidays, is this being worked on elsewhere / fixed by something else or is there anything I can do to aid in its resolution?

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

7 participants