[ButtonBase] Require host or ref forwarding components#13664
Conversation
|
@eps1lon I have no objection to this change. It makes me sad for the userland complexity it's adding but it's just following by the direction the React team took 🙏. Most people are using react-router, what's the interoperability story with them? Should we update the I would vote for waiting for the last moment to merge this pull request. I have a secret hope that React will provide a better answer to the problem before we have to release this change. |
|
Only really looked at this from an implementation point of view. Will look through all the usage again and investigate what plans react-router has for forwarding refs. Since Since this is targeted at |
e2fad77 to
6ddae5b
Compare
64c0c62 to
e23133d
Compare
Details of bundle changes.Comparing: a5b8011...0e354a5
|
f40a192 to
52b11f5
Compare
oliviertassinari
left a comment
There was a problem hiding this comment.
Should we replace the usage of buttonRef in the source and deprecate the ref?
| onTouchStart={this.handleTouchStart} | ||
| onContextMenu={this.handleContextMenu} | ||
| ref={innerRef || buttonRef} | ||
| ref={ref => { |
There was a problem hiding this comment.
What about creating an instance method not to call setRef every time the ButtonBase renders?
There was a problem hiding this comment.
Got the same idea when I read the review below 😄 Will investigate if we can configure a lint rule to check for this.
There was a problem hiding this comment.
This wouldn't handle change of props. This behavior is however required for the SpeedDial. Since it's an optimization we can tackle this in a different PR.
I try to avoid as much breaking changes as possible. I think we can make this smoother by forwarding refs in 4.0 (soft deprecate 1This includes |
f15df47 to
df06956
Compare
|
@eps1lon The soft deprecation for v4 sounds good to me. It's still a moving field. |
| // Fix for https://github.com/facebook/react/issues/7769 | ||
| if (!this.button) { | ||
| this.button = event.currentTarget; | ||
| if (!this.buttonRef.current) { |
There was a problem hiding this comment.
This branch is not covered anymore. The behavior was never tested anyway though. Researching the correct behavior that we would have to mock should be very expensive considering the age of the react issue. It essentially removes a false positive line coverage report.
BREAKING: components passed via `component` prop need to forward their refs.
Did you know that Prettier supports the markdown format 😱.
This reverts commit c4d4378. Was premature optimization which can cause subtle bugs if props changes. SpeedDial inparticual was relying on this behavior. Should be tackled separately.
df06956 to
0e354a5
Compare
| @@ -1,3 +1,4 @@ | |||
| /* eslint-disable react/no-multi-comp */ | |||
There was a problem hiding this comment.
I'm not a fan of this eslint react rule. What do you think of disabling it globally? Creating small components can be useful, creating a new file is an overhead. Should each function be into a different file, probably not. We don't enfoce it for functions. Why enforcing it for React components?
There was a problem hiding this comment.
Fully agree. It's not always clear when you should create an extra file. You could probably come up with some heuristic (LOC, number of instance fields or hooks etc) but what would that actually achieve?
I think this is one of those rules that you never explicitly follow until it rejects some code and then you disable it. Not useful at all IMO.
| /** | ||
| * Use that property to pass a ref callback to the native button component. | ||
| * @deprecated | ||
| * @deprecated Use `ref` instead |
There was a problem hiding this comment.
So, we gonna use the deprecatedPropType() helper in v4.1?
There was a problem hiding this comment.
That's the plan. The existence of this prop doesn't actually block us so we might as well defer a breaking change here so that migration is easier. I still have the typography v2 in mind and while the warnings were just to much in that case it is still considered something you have to address when upgrading.
| } | ||
|
|
||
| getButtonNode() { | ||
| return ReactDOM.findDOMNode(this.buttonRef.current); |
There was a problem hiding this comment.
Smart. I guess findDOMNode only warns if the variable isn't a DOM element.
There was a problem hiding this comment.
I need to verify if that is actually tested in react or if there's confirmation for that behavior. It could very well be accidental at which point the whole findDOMNode migration becomes a lot trickier.
There was a problem hiding this comment.
Can we ask somebody from the React team?
There was a problem hiding this comment.
I'm writing a test and will submit this as a PR to react. We'll see what they'll say about it.

BREAKING: components passed via
componentprop need to be able to hold refs.