[styles] Improve ref forwarding#13676
Conversation
|
|
|
@oliviertassinari Currently things like |
|
@eps1lon How do you want to move forward? |
|
Sounds good, it's large enterprise, thank you for leading it! Do we still need |
|
I think we can keep it if users do something like |
|
Alright the issues described by @oliviertassinari are now solved. Only caveat is a deprecation warning in our docs now for |
| - It forwards *non React static* properties so this HOC is more "transparent". | ||
| - It forwards refs to the inner component. | ||
| - The `innerRef` prop is deprecated. Use `ref` instead. | ||
| - It does **not** copy over statics. |
| const ThemedDiv = withTheme()('div'); | ||
|
|
||
| mount( | ||
| <> |
There was a problem hiding this comment.
There was an issue with refs on root components when mounting in enzyme. I think I added a comment somewhere but this might've been on a local branch.
There was a problem hiding this comment.
@oliviertassinari I can't find the original issue unfortunately. However it does indeed break if I remove the fragment. ref.current will be undefined.
|
@material-ui/styles: parsed: -3.06% 😍, gzip: -2.18% 😍 Details of bundle changes.Comparing: 8d46415...ff974b3
|
3ea3061 to
4998d69
Compare
| @@ -1,4 +1,3 @@ | |||
| /* istanbul ignore file */ | |||
There was a problem hiding this comment.
I'm removing all the istanbul ignore, @eps1lon is right, let's leave the 100% utopia.
There was a problem hiding this comment.
To be fair that broken window analogy you linked made total sense to me. I just think that these comments won't help in that regard. At least this way we have the actual number to look at. Previously it was 100% (kind of; who knows how good it is actually). Now we know how good/bad we are and have tools helping us analyze it. Codesearch is not really that helpful IMO. It's like prefering // TODO over creating issues.
| 'Material-UI: The `innerRef` prop is deprecated and will be removed in v5. ' + | ||
| 'Refs are now automatically forwarded to the inner component.', | ||
| ); | ||
| // return new Error( |
There was a problem hiding this comment.
It's raising a warning as the ButtonBase is still using this API.
There was a problem hiding this comment.
Right. I think I annotated it with @deprecated somewhere to indicate a "soft deprecation". In a perfect world the eslint rule would detect these. I don't like runtime deprecation warnings that have the same level as any other warning (hello ReactDOM.findDOMNode). A lint rule makes more sense to me.
| const ref = React.createRef(); | ||
| mount( | ||
| <> | ||
| <React.Fragment> |
There was a problem hiding this comment.
What should we do with the Fragment. Should we embrace <> everywhere, should only use React.Fragment or it doesn't matter 🤔. I'm reducing entropy until we decide.
There was a problem hiding this comment.
I think React.Fragment is required if fragment refs land. So maybe enforce that?
|
I want to merge this pull request so I can finally complete #14560! |

Breaking change
withStylesandwithThemenow forward their refs to the decorated component:const Component = React.forwardRef((props, ref) => <div {...props} ref={ref} />); const StyledComponent = withStyles({})(Component); const ref = React.createRef(); - const rendered = <StyledComponent innerRef={ref} />; + const rendered = <StyledComponent ref={ref} />;refon the wrapped component to get a DOM node viarefuseRootRefinstead if you have no control over the componentconst Component = props => <div {...props} /> const StyledComponent = withStyles({})(Component); - const rendered = <StyledComponent ref={ref} />; + const rendered = <RootRef ref={ref}><StyledComponent ref={ref} /></RootRef>;or
React.forwardRefif you do have control:innerRefis being deprecated. It is however prioritized overref:@material-ui/stylesis still in alpha so the breaking change should not require a major version bump. It will be however breaking since we will use@material-ui/stylesin v4 over@material-ui/core/styles.