-
-
Notifications
You must be signed in to change notification settings - Fork 32.3k
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
Standardization of Callback Signatures #2957
Comments
Thanks for making this issue! 👍 I agree and am really looking forward to when this is done across the library. This topic is definitely one of my pain points with integrating material-ui into one of my projects. I'm sure this would make @mbrookes' library a good deal simpler too 😄 I haven't fully considered the implications of all your points (including point 5) but I definitely agree with this direction. I will continue to give it thought. I would be curious to hear your opinion regarding something like our
Does this mean you would recommend calling |
Of all the proposed core changes, this one may be the most painful, as it doesn't naturally allow for to deprecation warnings. One option may be to couple this with the component renaming to PascalCase, so that the old import returns the old callback signature, and vice-versa, and the deprecation warning for the old component name notes that the signature has changed in the new component. |
@newoga The only way we can know the reason is through the kind of event that was fired. events have pretty good API and support
These have nothing to do with controllable behavior. These are different This way, we can get rid of uncontrollable behavior with implementation of one single wrapper that understands this single standard: |
@mbrookes It will be painful for only a couple of components if we actually rename the props too. only a few of them are named |
Well, that's a good point! |
I guess we should look at this before #3096 to save duplication of effort. |
@mbrookes Great idea 👍 👍 But I think we better not make any more changes before the 0.15.0 release. the changes are so many as it is, I'd postpone it for the 0.16.0 release. Except maybe for the components that don't have onChange, so it would we a feature addition, not breaking change 😁 |
Really? Looking at the roadmap, I'm not seeing much in the way of true breaking changes. If users have been heeding the deprecation warnings, there shouldn't be any nasty surprises. Or is there more to come that's not listed there (but should be)? And to your point:
And I'm sure somewhere else we agreed sooner is better than later for breaking changes, as the more people use the library, the more are affected by a later breaking change. Just saying. 😁 |
I guess you have a point 😅, I think it would be a good idea to introduce some deprecations with the 0.15.0 release so we can make these standard. I'm just very afraid of callbacks. we can't warn users. we can't do any thing, and the effect might go unnoticed for a long time. we should heavily document the transition.
Yeah, that's scary O.o |
Well, sure, but that's what makes it a breaking change that had to wait for a 0.x release. I agree it's going to need a big-ass warning all over the place though! As well as the README and docs, we could have npm spit out a big warning using a postinstall script. Let me have a run through and see which components already have an |
Okay, here's what I found
Internal naming varies, but if we assume (value):
(event):
(event, value):
(event, index, value):
|
Wow, thanks a lot 👍 So we'll need only 3 breaking changes that we can't warn users about. For Tabs, DropDownMenu, SelectField. since LeftNav will have it's onChange removed, we can just use it for that purpose.
is being removed 😁 I'll update the issue description. 👍 Thanks a lot @mbrookes |
@newoga @oliviertassinari @mbrookes Please take another look at the title please 😁 |
@alitaheri I think I'm good moving forward with at least point 1 in the issue description. Maybe we could tackle the non-breaking changes components together as a PR and the breaking changes components individually in their own PRs so we can look more carefully, but otherwise I'm happy 👍 I agree with the general approach to moving toward stateless but haven't fully considered the design mentioned in points 2 and 3, but we can discuss that more in the future. |
@alitaheri thanks for taking my crib notes and turning it into a meaningful proposal! |
Just wanted to point out I only listed instances of To completely standardise the API, (step 1a? 😄 ) there are also the components that use something other than onChange (such as Those will be much less painful, as we can introduce |
@oliviertassinari Can 2 and 3 be moved to another release? |
Yeah, that sourds like a good idea. Let's reduce the scope of this big upcoming release. |
Have you considered adding flow to mui to guarantee this and aid in refactoring? I've got it setup in my new project and it has already helped a ton. Given that it is opt-in by default, we can add it class by class. I think it is something to consider given the size of the project. It should ease refactoring and maintainability, as well as integrate into CI to validate PRs. |
@rosskevin I personally prefer having a type system of any kind. But the issue is, not everyone know them. That means besides learning about our huge codebase, new contributors will also know about flow. That's not very good for big community-driven projects like this I'm afraid. |
Since it is opt-in, by the time they PR a class change there should be plenty of examples. Additionally, a PR can be submitted failing flow and we can help. I disagree that it doesn't apply. With the size, complexity, and many contributors, it is needed here more than most You described the proposal in flow terms; I think using flow is a critical step for maintainability. |
@alitaheri I agree, but can't we use flow without adding any type informations? |
@rosskevin I'm more of a typescript guy, I don't know flow myself 😅 As I said, I myself prefer a type system. But only if it's done in a way that doesn't slow down new comers. @oliviertassinari I haven't used flow in any of my projects, but if it's from the react guys, it should be smarter than most for react components. |
Flow and typescript are similar and on-par with each other (and often look very much the same). One nice thing about flow + react is that we can Many errors are found at compile time that you would normally miss in testing (or have to dramatically expand your test suite). |
One more note: you can add flow and wait to enforce it - it will have no affect on devs or users as it strips out the definitions at transpile time. |
@rosskevin Those are some decent points you've made. I don't disagree with any of them. Might not be a bad idea to open a proposal issue for it so we can get feedback from the community 👍 |
Added Flow proposal: #4515 |
what is the progress on this? |
I have a generic change data handler, which changes the underlying data based on the id of the component that fires the onChange event. I would like to be able to set the id of each of the material-ui components and for that id to either be set in the change event's |
We need to discuss how will we standardize the callbacks that some component take in order to behave in a controllable fashion. But since the signature of the callback function they accept is different across components, many new comers get confused.
Therefore, we have to come to a solution on this.
My proposal:
value
andonChange
props. No moreonRequestXxx
.value
must be as versatile as possible, if it make sense for it to be anything equatable with===
then it should be marked as any.falsy
EVER! Implicit coercion leads to many many bugs.(e: Event, v: value, ...rest: any[]) => void
reason
argument to indicate what triggered the change. The event can be checked against it's type or it's properties. I think this could be more accurate. (debatable 😁 )@oliviertassinari @newoga @mbrookes Tell me what you guys think 😁
The Roadmap:
1. Standardize The Following Components:
DatePicker: onChange(event, date)
DropDownMenu onChange(event, key, payload) => onChange(event, value, index)
, index?IconMenu (event, value)
Drawer (deprecated prop) onChange(event, key, payload) => onChange(event, state)
RadioButtonGroup onChange(event, newSelection)
SelectField, DropDownMenu onChange(event, index, value) => onChange(event, value, index)
Slider onChange(event, value)
Tabs onChange(value) => onChange(event, value)
[Tabs][BottomNavigation] Use value over index property #7741TextField onChange(event) => onChange(event, value)
[TextField] Standardize onChange callback and remove valueLink #3699TimePicker onChange(null, time) => onChange(event, time)
Table
([Table] Send event object after click, hover, hoverOut on cell. #3002)2. Purge State:
StateWrapper
components that can be used to make components stateful, useful for forms. It must implement:getValue()
,setValue(value)
,clearValue()
,defaultValue prop
,onChange prop: (event, value, ...rest) => void
3. Documentation and deployment:
This is easy to implement, but I don't know if we want this, we should discuss this too.
The text was updated successfully, but these errors were encountered: