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

[SelectInput] Fix event forwarding #8386

Merged
merged 8 commits into from Sep 25, 2017

Conversation

cherniavskii
Copy link
Member

@cherniavskii cherniavskii commented Sep 25, 2017

Fixes #8381

@cherniavskii
Copy link
Member Author

cherniavskii commented Sep 25, 2017

I'm having problems with flow, which I'm not familiar with.
@rosskevin can you take a look?

@@ -53,7 +53,7 @@ export type Props = {
* @param {object} event The event source of the callback
* @param {object} child The react element that was selected
*/
onChange?: (event: Object, child: Element<*>) => void,
onChange?: (event: SyntheticMouseEvent<*>, child: Element<*>) => void,
Copy link
Member

Choose a reason for hiding this comment

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

I believe this should probably be the more super SyntheticUIEvent<> (parent class to SyntheticMouseEvent)

);
event.persist();
// $FlowFixMe
event.target = { ...event.target, value };
Copy link
Member

Choose a reason for hiding this comment

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

Should not use $FlowFixMe. You need to implement a type refinement: https://flow.org/en/docs/lang/refinements/

That's fancy for saying you need to check first for the existence of target. It is not guaranteed to be there. Here's a link to the definition:
https://github.com/facebook/flow/blob/5c9deb498ca0b523243a8fda40160333f1f23277/lib/react.js#L408

And a flow cheatsheet (bookmark this):
https://www.saltycrane.com/flow-type-cheat-sheet/latest/

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks for your help! :)
Pushed a fix, let me know if it's ok

// $FlowFixMe
event.target = { ...event.target, value };
// $FlowFixMe
this.props.onChange(event, child);
Copy link
Member

Choose a reason for hiding this comment

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

$FlowFixMe should not be needed, let's solve the problem. We should not introduce workarounds into a hardened codebase, I don't want to accept PRs with $FlowFixMe unless it is a last resort, which I am unconvinced it is in this case.

@@ -114,14 +114,15 @@ class SelectInput extends React.Component<AllProps, State> {
});
};

handleItemClick = (child: Element<*>) => (event: SyntheticMouseEvent<>) => {
handleItemClick = (child: Element<*>) => (event: SyntheticMouseEvent<> & { target: Object }) => {
Copy link
Member

Choose a reason for hiding this comment

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

No, you are artificially claiming that anything passed into here has a target, which is not true.

Copy link
Member Author

Choose a reason for hiding this comment

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

If I understand properly, target should be optional here, and also before doing ...event.target I should check if target is present in event. Am I right?

Copy link
Member

Choose a reason for hiding this comment

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

In the above, you are fabricating a new type using an intersection. Since we are not in control of these types, we should not be trying to alter them.

Checking presence of target is the right thing to do, since we cannot have concrete type information at this point in the handling process.

@@ -114,15 +114,21 @@ class SelectInput extends React.Component<AllProps, State> {
});
};

handleItemClick = (child: Element<*>) => (event: SyntheticMouseEvent<>) => {
handleItemClick = (child: Element<*>) => (event: SyntheticMouseEvent<> & { target?: Object }) => {
Copy link
Member

@rosskevin rosskevin Sep 25, 2017

Choose a reason for hiding this comment

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

Event is not in our control, therefore we should not be fabricating a type. It is what it is, so you must add a dynamic check (type refinement) to see if target is present.

So, this can only be event: SyntheticMouseEvent<> the way I read it.

Copy link
Member Author

Choose a reason for hiding this comment

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

There already is a type refinement for target, so the last thing to do is to change target's type to any?

@rosskevin
Copy link
Member

rosskevin commented Sep 25, 2017

@cherniavskii you may encounter a bug I found with with flow-bin 0.55, and may require a rollback to 54.1 if I am right they don't have a fix quickly - facebook/flow#4966

Just for sanity, as you try to fix your code, you might roll the flow-bin version back to 0.54.1 just because it is a known-good version. I'm pretty confident 0.55 has a problem.

@cherniavskii
Copy link
Member Author

@rosskevin thanks for your time!
Should I change anything or just wait until it will be fixed in 55?

@rosskevin
Copy link
Member

Roll back flow-bin to ^0.54.1 and check your code. I'll accept the package.json version change, just make sure your code works with that.

@cherniavskii
Copy link
Member Author

@rosskevin Actually code from my latest commit works on 55 too. Or should I use SyntheticEvent<> instead of SyntheticMouseEvent<> to be able reproduce that bug?

@oliviertassinari oliviertassinari added component: select This is the name of the generic UI component, not the React module! bug 🐛 Something doesn't work v1 labels Sep 25, 2017
@oliviertassinari
Copy link
Member

@rosskevin Anything preventing us from merging the PR?

@rosskevin rosskevin merged commit 1c3d770 into mui:v1-beta Sep 25, 2017
@cherniavskii cherniavskii deleted the select-input-event-fix branch September 28, 2017 16:51
@oliviertassinari oliviertassinari changed the title [SelectInput] fix event forwarding [SelectInput] Fix event forwarding Sep 30, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug 🐛 Something doesn't work component: select This is the name of the generic UI component, not the React module!
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants