-
-
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
Migrate components to ES6 Classes #458
Comments
I'd be more than happy to help work on this and migrate components and the docs/ example to the new ES6 Classes and etc. |
What about mixins? |
I'm not sure actually. It appears like the main Mixin to get rid of is |
@BobertForever I would hold off until after our css refactoring is complete, so we can avoid too many merge conflicts. Currently, Classable is used to allow users to apply their custom styles to components. It looks like React will not have mixin support for ES6 classes at least not anytime soon, so we might have to stick with |
Would creating a |
the problem comes when you have more than one mixin, as we will have in many of the components after the css refactoring is done. https://github.com/callemall/material-ui/blob/css-in-js/src/js/mixins/style-propable.js |
Hmm... I'm trying to think of a solution to that. There's the chained |
Just perusing this issue tracker and thought I'd drop my unsolicited 2 cents... here's an approach to es6 mixins |
I would recommend take this approach: |
I am not fully understand. React router is removing mixin with router context https://github.com/rackt/react-router/blob/master/docs/api/RouterContext.md |
@yathit that was actually addressed in a few pull requests recently. Material-UI now uses the new React-router context style, not the mixins. |
There is a react mixin decorator converting mixins to decorators |
First attent #1734 |
Is there any update on this? The actual style-propable mixin says it is unnecessary after v0.11, right now it's on v0.13.x I'm having all sorts of issues using material-ui with es6 classes. :( Edit: Please disregard this, I was able to finally follow this guid successfully. My error was due to something else. Sorry. |
@bpmckee Does that mean that if you follow that guide, you no longer need StylesPropable? I've been studying the docs example and they use the various mixins all over the place. I'm building a strictly ES6/ES7 project, so I need to know which mixins are still necessary so that I can find a workaround.. |
That's correct. Granted, I'm just getting into the library but I haven't had the need to use any mixins. For example I could have a component like this (and it'd be styled correctly based on my raw theme). import React from 'react';
import { AppCanvas, AppBar } from 'material-ui';
// NOTE: import the theme manager like this, apparently doing it any other way grabs the wrong one
import ThemeManager from 'material-ui/lib/styles/theme-manager';
import themeDecorator from 'material-ui/lib/styles/theme-decorator';
import myRawTheme from './myRawTheme';
@themeDecorator(ThemeManager.getMuiTheme(myRawTheme))
export default class MyComponent extends React.Component {
render() {
return (
<AppBar title="Test" />
<h1>The app bar is styled based on my raw theme</h1>
);
}
} I actually got a lot of this from http://material-ui.com/#/customization/themes which is a lot different than the docs example I was trying to follow when I asked the question initially. |
It's been a while since I've looked at this; would using a Stage 1 decorator on the class to handle the mixin be a valid way to migrate the components over to the new syntax? I'm currently doing that for my React project and I've been loving the new syntax and style. It keeps the code working exactly the same as you have it but allows you to upgrade the syntax. From there you could later deprecate the mixin if that's your end-goal. I see @bpmckee suggested something similar, but my proposal would make this: import React from 'react';
import ContextPure from '../mixins/context-pure';
import StylePropable from '../mixins/style-propable';
import DefaultRawTheme from '../styles/raw-themes/light-raw-theme';
import ThemeManager from '../styles/theme-manager';
const FlatButtonLabel = React.createClass({
mixins: [
ContextPure,
StylePropable,
],
contextTypes: {
muiTheme: React.PropTypes.object,
},
propTypes: {
label: React.PropTypes.node,
style: React.PropTypes.object,
},
//for passing default theme context to children
childContextTypes: {
muiTheme: React.PropTypes.object,
},
getChildContext() {
return {
muiTheme: this.state.muiTheme,
};
},
getInitialState() {
return {
muiTheme: this.context.muiTheme ? this.context.muiTheme : ThemeManager.getMuiTheme(DefaultRawTheme),
};
},
//to update theme inside state whenever a new theme is passed down
//from the parent / owner using context
componentWillReceiveProps(nextProps, nextContext) {
let newMuiTheme = nextContext.muiTheme ? nextContext.muiTheme : this.state.muiTheme;
this.setState({muiTheme: newMuiTheme});
},
statics: {
getRelevantContextKeys(muiTheme) {
return {
spacingDesktopGutterLess: muiTheme.rawTheme.spacing.desktopGutterLess,
};
},
},
render: function() {
const {
label,
style,
} = this.props;
const contextKeys = this.constructor.getRelevantContextKeys(this.state.muiTheme);
const mergedRootStyles = this.mergeStyles({
position: 'relative',
padding: '0 ' + contextKeys.spacingDesktopGutterLess + 'px',
}, style);
return (
<span style={this.prepareStyles(mergedRootStyles)}>{label}</span>
);
},
});
export default FlatButtonLabel; Look like this: import React from 'react';
import ContextPure from '../mixins/context-pure';
import StylePropable from '../mixins/style-propable';
import DefaultRawTheme from '../styles/raw-themes/light-raw-theme';
import ThemeManager from '../styles/theme-manager';
import { mixin } from 'core-decorators';
@mixin(ContextPure, StylePropable)
export default class FlatButtonLabel extends React.Component {
constructor(props) {
super(props);
this.state = {
muiTheme: this.context.muiTheme
? this.context.muiTheme
: ThemeManager.getMuiTheme(DefaultRawTheme),
};
}
static contextTypes = {
muiTheme: React.PropTypes.object,
}
static propTypes = {
label: React.PropTypes.node,
style: React.PropTypes.object,
}
//for passing default theme context to children
static childContextTypes = {
muiTheme: React.PropTypes.object,
}
getChildContext() {
return {
muiTheme: this.state.muiTheme,
};
}
//to update theme inside state whenever a new theme is passed down
//from the parent / owner using context
componentWillReceiveProps(nextProps, nextContext) {
let newMuiTheme = nextContext.muiTheme ? nextContext.muiTheme : this.state.muiTheme;
this.setState({muiTheme: newMuiTheme});
}
static getRelevantContextKeys(muiTheme) {
return {
spacingDesktopGutterLess: muiTheme.rawTheme.spacing.desktopGutterLess,
};
}
render() {
const {
label,
style,
} = this.props;
const contextKeys = this.constructor.getRelevantContextKeys(this.state.muiTheme);
const mergedRootStyles = this.mergeStyles({
position: 'relative',
padding: '0 ' + contextKeys.spacingDesktopGutterLess + 'px',
}, style);
return (
<span style={this.prepareStyles(mergedRootStyles)}>{label}</span>
);
}
} |
@oliviertassinari and @subjectix, I see you're the most active maintainers as of late; I just wanted to tag you since this issue is kind of old and I'd be interested in doing a lot of the work I suggested above if desired. |
@BobertForever Well, I think that this work should be done by a code migration tool, as facebook is doing it with his codebase. I'm preaty sure those tools are already available, this shouldn't be too much work. |
Yeah, react-codemod does a lot of the conversion to es6, but not the mixin step. I can run it and fix the mixins and have a PR up? |
@BobertForever I'm also a C# developer, so classes all the way 👍 👍 But I think minix are anti patterns all the way too. You can see even the craetors of React bragging about it 😁. We should move those mixin methods to either library functions (a LOT easier to track, debug, reason about, etc) and the tightly coupled ones to HOCs @oliviertassinari Ideas? |
@oliviertassinari I'm going to create a milestone to address this. are you ok with it? |
@subjectix Yeah I agree in regards to the mixins, I'm just proposing an intermediate step while the more difficult work of removing them all together is being considered. I think jumping from having mixins to es6 AND not having mixins is a bit much, especially saying as there is no plan (from what I can tell) to get rid of them in the repo's current state. |
@BobertForever It's a lot safer to first remove mixins from the library and then migrate to es6. Because then maybe we can use tools to conver to es6 with comfort. |
After doing some experimentation, the tool provided by Facebook doesn't handle es7 things at all, such as All in all the tool did all the work and I just fixed the mixin. |
@BobertForever If we remove all the mixins first we can omit decorators and save ourselves from one dependency. @oliviertassinari Thoughts? |
@subjectix I also used that dependency for the decorator to autobind I will defer to your thoughts, though. |
That's almost done with #3843 🎉. |
Specifically in the new React version, ES6 Classes were introduced, amongst other features. Is there any work being done/ can a branch be opened to start work on this so the peer dependency can be updated? I know they're not dependent on each other but upgrading the library to comply with the new design would be an awesome step forward.
The text was updated successfully, but these errors were encountered: