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

[Toolbar] Remove style-propable mixin #3180

Merged
merged 1 commit into from
Feb 5, 2016

Conversation

newoga
Copy link
Contributor

@newoga newoga commented Feb 4, 2016

@oliviertassinari @alitaheri @mbrookes

This isn't done, as I'm migrating the code, I wanted to get your feedback on this pattern of moving getStyles() outside of the class declaration (and changing the method signature to getStyles(props, state).

I think this approach has the following benefits:

  1. Reduces component surface API (and imperative methods) which is safer and allows us to move more towards functional components
  2. Prevents leaky abstractions and prevents developers from implementing custom styling and behavior from undocumented methods (Disclosure: I am not trying to say anything bad about this developer 😁. I perfectly understand what and why he was doing what he was doing, but I still think we should find a better way for material-ui to handle his use case and prevent developers from falling into the trap of using internal API)
  3. Discourages the use of other instance methods to calculate style such this.getTheme() and this.getSpacing()
  4. Forces us (and other contributors) to think of style as a function of props and state (and ideally in the future just a function of props)
  5. It's more functional, predictable, and reusable (could open up interesting opportunities in the future like composition and more)

Final note: This PR was originally the start of migrating the toolbar components off of style-propable. After we decide, I'll rename the PR and finish that work.

Signed-off-by: Neil Gabbadon neil.gabbadon@emikra.com

@oliviertassinari
Copy link
Member

@newoga I think that it's an excellent idea!

@newoga
Copy link
Contributor Author

newoga commented Feb 4, 2016

@newoga I think that it's an excellent idea!

I'm glad, I think this change would make me very happy. 😆

@alitaheri
Copy link
Member

Pure awesomeness and conciseness 👍 👍 This will bring us very close to memoization 😍

@newoga
Copy link
Contributor Author

newoga commented Feb 4, 2016

Pure awesomeness and conciseness 👍 👍 This will bring us very close to memoization 😍

Let's do it! 😄 🎉

I applied that pattern to the rest of the components under ./toolbar. Take a look please 😁

},

getTheme() {
return this.state.muiTheme.toolbar;
_handleMouseEnterFontIcon: (style) => (e) => {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I want to draw your attention here for feed back.

The previous implementation was recomputed the whole style object for each property on mouse enter and leave:

_handleMouseEnterFontIcon(e) {
  e.target.style.zIndex = this.getStyles().icon.hover.zIndex;
e.target.style.color = this.getStyles().icon.hover.color;
},

I replaced it with a higher order function so that the style object is only computed once per render. Honestly, if I had my way, we would move these outside of the class too! 😁

If these were removed, the only time this. is called is for these three scenarios:

  1. this.props
  2. this.setState({muiTheme: aMuiTheme})
  3. this.state.muiTheme

It's so close to being purely functional!

Copy link
Member

Choose a reason for hiding this comment

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

Yeah! That would be great. But it's going to need a lot of thought. I think an HOC that can handle these interactions would make this stateless (an a whole lot of other components) but I don't know how that is possible.

@newoga newoga changed the title [RFC] [Toolbar] Externalize getStyle() functions [Toolbar] Remove style-propable mixin Feb 5, 2016
@newoga newoga added PR: needs revision The pull request can't be merged. More details is available on the code review or fails in the CI and removed PR: Needs Review labels Feb 5, 2016
Signed-off-by: Neil Gabbadon <neil.gabbadon@emikra.com>
@newoga newoga added PR: Needs Review and removed PR: needs revision The pull request can't be merged. More details is available on the code review or fails in the CI labels Feb 5, 2016
@newoga
Copy link
Contributor Author

newoga commented Feb 5, 2016

Done, change setState to nextContext.muiTheme || this.state.muiTheme

@@ -197,7 +196,7 @@ const ToolbarGroup = React.createClass({
}, this);

return (
<div {...other} className={className} style={this.prepareStyles(styles.root, style)}>
<div {...other} className={className} style={prepareStyles(Object.assign({}, styles.root, style))}>
Copy link
Member

Choose a reason for hiding this comment

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

I see you're doing this almost everywhere you use prepareStyles maybe it's time to move the logic before we merge these? @oliviertassinari What do you think?

Copy link
Member

Choose a reason for hiding this comment

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

I don't follow. What would be the advantage?

Copy link
Member

Choose a reason for hiding this comment

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

well since it's gonna show up everywhere, why not just put it in the prepareStyles function in the first place. this way we won't have to make the assumption that the styles passed down to prepareStyles are safe to mutate. we'll just make them safe ourselves.

Copy link
Member

Choose a reason for hiding this comment

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

That's fair. I see a performance concern in this approach. 50%+ of the time, the parameter passed to the prepareStyles is safe to mutate. I feel like we will end up with more Object.assign({}, with your solution.

However, in this line I think that prepareStyles(Object.assign(styles.root, style)) would work just fine. But that's not 100% safe for future code changes (side effect).

Copy link
Member

Choose a reason for hiding this comment

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

I think more than 50% would be safe, you're right. Let's go with this approach for now 👍

@alitaheri
Copy link
Member

I'm all good. feel free to merge 👍

oliviertassinari added a commit that referenced this pull request Feb 5, 2016
[Toolbar] Remove style-propable mixin
@oliviertassinari oliviertassinari merged commit 0559b09 into mui:master Feb 5, 2016
@newoga newoga deleted the #2852/toolbar branch February 6, 2016 23:24
@zannager zannager added the component: Toolbar The React component. label Mar 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: Toolbar The React component.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants