You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
type declarations forbid ref e.g. <Button ref={handleRef} /> but allow innerRef for every component
The latter is wrong in some cases. E.g. The inner components of Paper or Backdrop are function components and can therefore not hold refs. It will trigger a runtime warning.
withStyles from @material-ui/core does not forward refs from ref but innerRef.
named props for refs can be problematic if multiple HOCs are used. E.g. Using styled-components to style material-ui components will prevent innerRef from being passed to the inner material-ui component.
Proposal
explicitly document ref
Couple of alternatives:
We could start by collecting what components allow this at the moment (basically every component wrapped in withStyles). This will break in v4 if [styles] Improve ref forwarding #13676 is accepted
Disallow ref on all of our components. If the DOM node is required RootRef should be used.
The type declarations follow from the documentation.
ref in v4
With #13676 and the replacement of @material-ui/core/styles with @material-ui/styles as our internal styling solution <Button ref /> would return the ref to the inner component by default. In it's current state some components would loose the ability to hold ref (e.g. AppBar).
There is an argument to be made that ref inherently cause all sorts of problems in general. However I would argue that all of our components return some html element. Interfacing our components so that they only return a ref to an abstract HTMLElement should therefore cause no problems in the future. It doesn't bind us to any specific implementation (other than a html element). This allows e.g. layout computations if necessary or imperative focus which is what we use internally.
I'm in favor of enabling refs on all of our existing components. It allows for a simpler API where one doesn't have to look at the API docs for every single component and check if it allows ref (and then be annoyed because we didn't have your use case in mind). (Although TS users can be lazy and don't have to check API docs).
Summary
Add explicit documentation
Fix typescript declarations
One of
Disallow ref on all components i.e. use ref at your own risk. Prefer RootRef if you need the DOM node
RootRef will trigger findDOMNode deprecation warnings
refs in v3
refe.g.<Button ref={handleRef} />but allowinnerReffor every componentPaperorBackdropare function components and can therefore not hold refs. It will trigger a runtime warning.withStylesfrom@material-ui/coredoes not forward refs fromrefbutinnerRef.refscan be problematic if multiple HOCs are used. E.g. Usingstyled-componentsto style material-ui components will preventinnerReffrom being passed to the inner material-ui component.Proposal
explicitly document
refCouple of alternatives:
withStyles). This will break in v4 if [styles] Improve ref forwarding #13676 is acceptedrefon all of our components. If the DOM node is requiredRootRefshould be used.The type declarations follow from the documentation.
refin v4With #13676 and the replacement of
@material-ui/core/styleswith@material-ui/stylesas our internal styling solution<Button ref />would return the ref to the inner component by default. In it's current state some components would loose the ability to holdref(e.g.AppBar).There is an argument to be made that
refinherently cause all sorts of problems in general. However I would argue that all of our components return some html element. Interfacing our components so that they only return arefto an abstractHTMLElementshould therefore cause no problems in the future. It doesn't bind us to any specific implementation (other than a html element). This allows e.g. layout computations if necessary or imperativefocuswhich is what we use internally.I'm in favor of enabling
refson all of our existing components. It allows for a simpler API where one doesn't have to look at the API docs for every single component and check if it allowsref(and then be annoyed because we didn't have your use case in mind). (Although TS users can be lazy and don't have to check API docs).Summary
refon all components i.e. userefat your own risk. PreferRootRefif you need the DOM nodeRootRefwill triggerfindDOMNodedeprecation warningsrefbehavior for inner components.refbehavior on actual component will change though with [styles] Improve ref forwarding #13676.findDOMNoderefon all components. Interface it as a abstractHTMLElementConfirmed
Currently missing (strike through means not applicable, some might already work but are not picked up by our docs generator)
[ ] TouchRipple.js(need imperative handle)[ ] ClickAwayListener.jsno host component rendered[ ] CssBaseline.jsno host component rendered[ ] Fade.jsno host component rendered[ ] Grow.jsno host component rendered[ ] Hidden.jsno host component rendered[ ] ListItemAvatar.jsno host component rendered[ ] NoSsr.jsno host component rendered[ ] Portal.jsno host component rendered[ ] RootRef.jsno host component rendered[ ] Zoom.jsno host component rendered[ ] Slide.jsno host component rendered[ ] Tooltip.jsRenders children as root, PopperProps available[ ] SpeedDialIcon.jslab has low priority[ ] Slider.jslab has low priority[ ] SpeedDialAction.jslab has low priority[ ] SpeedDial.jslab has low priority[ ] ToggleButton.jslab has low priority[ ] ToggleButtonGroup.jslab has low priorityResources
RootRef/cc @mui-org/core-contributors