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

fix(core / styled): fix wrap the display name in styled and withEmotionCache #1692

Closed
wants to merge 3 commits into from

Conversation

zthxxx
Copy link

@zthxxx zthxxx commented Dec 15, 2019

What: display correct styled component's name in React DevTools

Why:

@emotion/styled use withEmotionCache function which is a HOC but not wrap a displayName.

So in React DevTools, it will be always show only render string as component name.

Before wrap displayName:

image

How:

Follow React displayName docs, inject displayName before and into withEmotionCache.

After wrap displayName:

image

Checklist:

  • Documentation N/A
  • Tests N/A
  • Code complete
  • Changeset

@changeset-bot
Copy link

changeset-bot bot commented Dec 15, 2019

🦋 Changeset is good to go

Latest commit: eea168b

We got this.

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@codecov
Copy link

codecov bot commented Dec 15, 2019

Codecov Report

Merging #1692 into master will increase coverage by <.01%.
The diff coverage is 100%.

Impacted Files Coverage Δ
packages/styled-base/src/index.js 100% <100%> (ø) ⬆️
packages/core/src/context.js 100% <100%> (ø) ⬆️

@zthxxx
Copy link
Author

zthxxx commented Dec 15, 2019

cc @Andarist

})`

const injectDisplayName = Component => {
Component.displayName = Component.displayName || displayName
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is no way for the Component to have a .displayName as it's always the anonymous function

@@ -78,8 +92,8 @@ let createStyled: CreateStyled = (tag: any, options?: StyledOptions) => {
}

// $FlowFixMe: we need to cast StatelessFunctionalComponent to our PrivateStyledComponent class
const Styled: PrivateStyledComponent<P> = withEmotionCache(
(props, context, ref) => {
const Styled: PrivateStyledComponent<P> = withEmotionCache<P>(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead of doing this injectDisplayName I think it could be more readable if we could just split this into separate statements, like this:

const render = (props, context, ref) => {}
render.displayName = displayName
const Styled = withEmotionCache(render)

That being said - shouldn't we also make this displayName in here a little bit more distinct? Right now 2 component will receive the very same displayName from what I can see (the one being this render here and the other one being Styled)

Copy link
Author

@zthxxx zthxxx Dec 15, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right now 2 component will receive the very same displayName from what I can see

In my practice, I found that Styled.displayName has no effect.

Origin Styled.displayName got the result as the screenshots shown above.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But first, i wrote codes like yours comment, but i found some problems that

  • its less semantic than injectDisplayNameToComponent(Component, displayName) func

  • if you want use the same code to solve same problems with other codes where withEmotionCache used, it will make lots of code changed;

    On the other hand injectDisplayName func is reusable logic if export and necessary

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found that Styled.displayName has no effect.

i guess, its due to forwardRef in HOC

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i guess, its due to forwardRef in HOC

yes, source code at forwardRef.js#L46

seems do not accept Component.displayName after forwardRef return;

some POC codes and results here:

屏幕快照 2019-12-15 下午8 24 30

屏幕快照 2019-12-15 下午8 25 08

屏幕快照 2019-12-15 下午8 29 17

@@ -32,6 +45,9 @@ let withEmotionCache = function withEmotionCache<Props>(
</EmotionCacheContext.Consumer>
)
}

render.displayName = getDisplayName<Props>(func)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does func have a name under any circumstances? I think we always pass anonymous functions to it

Copy link
Author

@zthxxx zthxxx Dec 15, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not before, so I made injectDisplayName in styled-base to inject displayName before withEmotionCache,
the func still has no name property yet, but maybe post in the future in withEmotionCache, then withEmotionCache also ability to use name.

@zthxxx
Copy link
Author

zthxxx commented Dec 15, 2019

I try to fix it in react devtools in facebook/react#17613

@Andarist
Copy link
Member

Hm, this seems like some sort of regression in devtools. I've found a PR supposedly fixing this: https://github.com/facebook/react-devtools/pull/1154/files

@zthxxx
Copy link
Author

zthxxx commented Dec 16, 2019

yep, I think it's actually a problem in React DevTools.

@zthxxx zthxxx closed this Dec 16, 2019
@zthxxx
Copy link
Author

zthxxx commented Dec 18, 2019

Thanks for review, I have fixed the real reason in facebook/react#17613

@Andarist
Copy link
Member

No problem, I'm glad that you have fixed this in devtools ❤️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants