9 ms·
React on ES6+
- jozan 11y agoWhat's the status of mixins? How could I do something similar in terms of functionality in ES6?
- shangxiao 11y agoNot yet supported afaik [1]. I've used react-mixin [2] with some success. [1] https://facebook.github.io/react/blog/2015/01/27/react-v0.13.0-beta-1.html#mixins https://facebook.github.io/react/blog/2015/01/27/react-v0.13... [2] https://github.com/brigand/react-mixin https://github.com/brigand/react-mixin
- egeozcan 11y agoLooks like a great idea, a nice intermediate step while the decorators are not widely used. I wonder what didn't work out as you said "some success"?
- STRML 11y agoWe have a few rather complex mixins in React-Router-Component and react-mixin's decorators worked just fine [1]. The only limitation I see now is a mixin that defines more mixins; this currently doesn't work, but there's no reason why it couldn't. I am considering a patch. 1. https://github.com/STRML/react-router-component/blob/master/examples/es6/app.js#L11 https://github.com/STRML/react-router-component/blob/master/...
- egeozcan 11y agoThank you for the heads up and the example. > The only limitation I see now is a mixin that defines more mixins; this currently doesn't work Why and how would you do this?
- STRML 11y agoIt's just a nice way to split up concerns. In React-Router-Component, the RouterMixin [1] mixes in the Environment Mixin [2] which allows the Environment to address its own concerns in a separate file and to be included in other, custom components. 1. https://github.com/STRML/react-router-component/blob/master/lib/RouterMixin.js#L9 https://github.com/STRML/react-router-component/blob/master/... 2. https://github.com/STRML/react-router-component/blob/master/lib/environment/index.js#L12 https://github.com/STRML/react-router-component/blob/master/...
- egeozcan 11y agoAh, now I get it, you meant nested mixins. Great, thanks for the pull, hope it gets merged.
- STRML 11y agoI've submitted a fix for this in react-mixin here. https://github.com/brigand/react-mixin/pull/22 https://github.com/brigand/react-mixin/pull/22
- sahat 11y agoMeh, mixins are anti-pattern and I am glad they are finally gone. In my experience mixins just make your code hard to read.
- MrOrelliOReilly 11y agoI never understood this line of reasoning. Isn't composition over inheritance a valid principle, especially in JS land? Speaking more to the anti-pattern part of your comment, obviously whether or not you think they are hard to read is subjective.
- Lazare 11y agoAgreed 100%. I find inheritance much harder to reason about or even read. Mixins don't always lead to the clearest code, but they're better than all the alternatives.
- kyleashipley 11y agoI don't think that avoiding mixins implies inheritance. The more common pattern, at least in React, is "higher-order" or "wrapper" components where the responsibility for managing the mixin's behavior is moved into a separate, composable component. The main issue with mixins is that the origin of behavior becomes opaque. If I call this.mixinFunction(), it's not defined in my file or imported directly, so I have to know exactly which functions come from which mixins. With higher-order components, you can just look at the props and know where things originated. I'm not a staunch defender of any particular approach, but I think that's the main argument against mixins. (And it applies to other languages as well, such as Ruby.)
- Lazare 11y agoMmm, not sure I see a huge difference between: import Foo from './foo'; let Bar == React.createClass({}); Bar = Foo(Bar); Bar.mixinFunction(); and: import Foo from './foo'; let Bar == React.crateClass({mixins: Foo}); Bar.mixinFunction(); In both cases I'm adding functions to my Bar component; in neither case is it defined in my file or added directly. It is true that in the general case the mixin approach would mutate the internal state of Bar, whereas the higher-order component approach would re-render Bar with updated props, which is a solid win for the latter style. (Conversely, a mixin can check the state of the underlying component, while a higher-order component cannot, which means that you can't really implement shouldComponentUpdate as a higher-order component.) But it's really a fairly subtle difference, and I wouldn't say that either is particularly more transparent. :)
- lukasm 11y agoYou have 3 options if you want mixin behaviour: - Use old syntax or explicitly add mixin to prototype - Use composition. A bit annoying, because you have to make an extra class class OuterComponent extends React.Component { render() { return ( <MixinComponent> <InnerComponent /> </MixinComponent> ); } } class InnerComponent extends React.Component{} - wait for decorators (?)
- eskimobloood 11y agoYou can at least try decorators with babel using[1] $ babel --optional es7.decorators or babel.transform("code", { optional: ["es7.decorators"] }); Here[2] is an article that describes how to use it for mixins [1] https://babeljs.io/docs/usage/experimental https://babeljs.io/docs/usage/experimental [2] http://raganwald.com/2015/06/26/decorators-in-es7.html http://raganwald.com/2015/06/26/decorators-in-es7.html
- adjohu 11y agoMost stuff I've seen is using decorators to enhance components (which seems like a better practice than mixins)
- drapper 11y agoPossibly decorators proposed for ES7 would be a solution here? Babel and TypeScript already support them. By the way, TypeScript recently (in nightly) gained support for JSX, so we can now have all of this ES6 stuff + types on top of it.
- davedx 11y agoI've been working on a ES6 composition-based library that might help out here: https://www.npmjs.com/package/fabricant https://www.npmjs.com/package/fabricant The idea is you declare which components will be needed and the library takes care of instantiating objects with the necessary components for you. It works something like Unity (the game engine)'s entity-component architecture. I haven't tried to get it working with React yet though, I've been playing with threejs instead :)
- inglor 11y agoMixins are being considered for ES2016: https://esdiscuss.org/topic/about-lightweight-traits https://esdiscuss.org/topic/about-lightweight-traits meanwhile you can Object.assign behavior into things.
- crossman 11y agoI wrote a small utility for using mixins with my React components. I've been finding it really useful. The notes assume you're using ES7 decorators. But you could easily use it with ES5/6 syntax by treating it as a normal function and just passing your class to it. https://www.npmjs.com/package/mixin-decorator https://www.npmjs.com/package/mixin-decorator edit: a link would be helpful, right?
- deanclatworthy 11y agoLooks to be a nice improvement. The only thing that really bothers me is if they deprecate componentDidMount. I think it's a lot more verbose than using the constructor method, especially given the corresponding componentDidUnmount method still exists. Is there a destructor syntax for ES6?
- HugoDaniel 11y agoThese new syntactic sugar additions are great for lazy fat-prone people like me :)
- dugmartin 11y agoI understand the interest in new Javascript standards in the browser however I've been doing a lot of React+CoffeeScript (without JSX) work lately and it can do all of what is mentioned in the article in a more expressive and (imho) more beautiful syntax. I'm genuinely curious about all the ES6/ES7 articles. Is the interest driven from the eventual native support in future browsers and being able to drop transpiler dependencies?
- mytranspiler 11y agoWhats the state on coffeescript+jsx these days? I had a horrible time getting it transpile correctly (with gulp) about a year ago.
- epmatsw 11y agoWe've had pretty good success compiling cjsx with gulp-cjsx. The one annoyance I've noticed is that it's just a tad more finicky about whitespace and parentheses/brackets than normal coffeescript, but I suppose that's to be expected.
- mambodog 11y agoIf there is a particular case which you think should work but doesn't, please file an issue on the coffee-react-transform repo and I'll look into it.
- superplussed 11y agoThe code is just so clean. I never understand why it's not more widely used. The JSX blocks are just so clean without all of the braces and the like, and even get syntax highlighted as HTML in sublime.
- dugmartin 11y agoI stopped using JSX with React+CoffeeScript. I think the following looks a lot cleaner and removes the jsx dependency: {div, a} = React.DOM ... render: -> (div {}, (a {href: 'foo'}, 'bar') ) The only downside is having to extract the tags from React.DOM.
- thomasfoster96 11y agoThis might be a silly question, but was there ever any thought put towards using ES6 Template Strings rather than the JSX syntax additions? For example: class OuterComponent extends React.Component { render() { return ( <MixinComponent> <InnerComponent /> </MixinComponent> ); } } Being replaced by something more like: class OuterComponent extends React.Component { render() { return JSX` <MixinComponent> <InnerComponent /> </MixinComponent> `; } }
- Honzo 11y agoWould you be able to use template strings inside the template if this was the case?
- k__ 11y agoGood point. Since JSX is just JavaScript, it doesn't have any problems with nesting.
- thomasfoster96 11y agoYes, template strings can be nested (well, they can using Babel).
- empyrical 11y agoThis works for me in the latest Chrome too: `${`test`}`
- ksherlock 11y agoSee also https://facebook.github.io/jsx/#why-not-template-literals https://facebook.github.io/jsx/#why-not-template-literals
- thomasfoster96 11y agoRightio, that sort of explains their rationale. Although this doesn't really help: However, this would lead to further divergence. Tooling that is built around the assumptions imposed by template literals wouldn't work. It would undermine the meaning of template literals. It would be necessary to define how JSX behaves within the rest of the ECMAScript grammar within the template literal anyway. I'm not really what the problem is here. Template strings seem to have been put in ES6 partly to do what JSX does, so it seems very odd that anyone went to the lengths of defining a language extension rather than use them.
- netcraft 11y agoDoes anyone have an example of an open source project that uses babel for react + es6? Usually for me the hardest part is setting up the project organization and plumbing to make everything work.
- dubcanada 11y agoAtom does I believe, but their build tool is really complicated.
- ssorallen 11y agoAtom uses CoffeeScript, but Nuclide[0], Facebook's suite of packages for Atom, uses ES6/7 (including async/await) via Babel. The transpilation and caching of transpiled sources is done in the nuclide-node-transpiler[1] package. [0] https://github.com/facebook/nuclide https://github.com/facebook/nuclide [1] https://github.com/facebook/nuclide/tree/master/pkg/nuclide/node-transpiler https://github.com/facebook/nuclide/tree/master/pkg/nuclide/...
- bryanlarsen 11y agoThis one looks pretty reasonable: http://jmfurlott.com/tutorial-setting-up-a-single-page-react-web-app-with-react-router-and-webpack/ http://jmfurlott.com/tutorial-setting-up-a-single-page-react... I recommend avoiding gulp and grunt and any other build systems. They're completely unnecessary. npm and webpack are sufficient. npm works well as a simple task runner, and there are webpack plugins to do pretty much anything you'd ever do with grunt or gulp.
- netcraft 11y agoCheers! this looks very helpful.
- k__ 11y agoI tried the webpack getting started tutorial [0] and just switched the css-loader in the tutorial for the babel-loader. Just took me half an hour from start to getting react+ES6 running. [0] http://webpack.github.io/docs/tutorials/getting-started/
- kendallpark 11y agoI'm using React in ES6 with Rails (the react-rails gem now uses Babel as its transpiler). What I've found is that I've had to choose between using ES6 and getting prerendering working correctly. I also couldn't get the ES6 modules working without RequireJS or CommonJS. If anyone has this figured out, I'd love to hear it.
- KurtMueller 11y agoThere's always the sprockets-commonjs gem, but it requires sprockets ~> 2.0 (sprockets-es6 requires sprockets ~> 3.0).
- kendallpark 11y agoYeah, I'm using the sprockets-es6 gem.
- KurtMueller 11y agohttps://github.com/justin808/react-webpack-rails-tutorial https://github.com/justin808/react-webpack-rails-tutorial Here's a tutorial on how somebody integrated webpack, react, and rails.
- feedjoelpie 11y agoI have it figured out. A long-winded explanation: Honestly I hate the react-rails gem. Whoever was maintaining it kept doing things at the whims of issue requestors. I remember one instance where they broke our apps with an upgrade because someone decided it would be a good idea to shim a definition for `window` into server prerenders. All because an issue creator who didn't really know what they were doing supposedly "needed" that to get browserify-rails working. So we made this: https://github.com/revelrylabs/execjs-rails https://github.com/revelrylabs/execjs-rails. That handles the server-side rendering for us. We only use react-rails for its assets, never for its helpers. And here's our own (always-evolving) layer on top of execjs-rails: http://toolkit.revelry.co/pages/core http://toolkit.revelry.co/pages/core. Examples are written in dusty JavaScript, but we've successfully used revelry_core with sprockets-es6 several times now. EDIT: Still no modules yet. It doesn't help that Josh Peek deleted the old sprockets-es6 repo and all its issues before passing off maintenance to someone else.)
- tel 11y agoC'mon. > Right away, you'll notice a subtle difference – a more terse syntax is available to you when defining classes: // The ES5 way var Photo = React.createClass({ handleDoubleTap(e) { … }, render() { … }, }); // The ES6+ way class Photo extends React.Component { handleDoubleTap(e) { … } render() { … } } It may or may not be more terse in longer examples, but ES6 already supports things to make the class syntax less terse here by about the same margin the article claims.
- adregan 11y agoWhile it doesn't add up to a terribly large amount of extra characters, you are missing the function keyword (ie. `handleDoubleTap: function(e)`) in the ES5 example.
- tel 11y agoAh, now I think I understand what they were trying to argue—full ES5 versus ES6 where I took it to be ES6 versus ES6-using-class.
- tel 11y agoMore Javascript `this` juggling. I really want to write a wrapper around `createClass` which just passes things as normal arguments.
- seivan 11y agoI haven't found any information on how to use libraries that depend on mixins for ES6. Say React-router, how would you use that if you're extending a class in ES6 and need to rely on that mixin?
- tranver 11y agoSince mixins are not supported in combination with classes[1] there is no way. I just fall back to React.createClass when I need mixins (afaik this is also what Facebook does). A lot of libraries, including react-router, are considering decorators as an alternative.[2] [1] http://facebook.github.io/react/blog/2015/01/27/react-v0.13.0-beta-1.html#mixins http://facebook.github.io/react/blog/2015/01/27/react-v0.13.... [2] https://github.com/rackt/react-router/issues/1173 https://github.com/rackt/react-router/issues/1173
- seivan 11y agoThanks! I suspected so, but I wasn't sure. I've found that you get a lot of messy variations when doing ES6 compared to sticking with ES5 or CoffeeScript. Not to mention the issues with all the god damn different build tools, it gets hard to get something standardised and good.
- smrtinsert 11y agowhere is the outrage over jsx syntax? why isnt anyone screaming for json now? is the bandwagon late?
- city41 11y agoThe react-starter-kit is a great way to dive head first into ES6 and React. Just clone the repo, npm install and go. It's fully up to date with all recent React and ES2015/2016 goodness. https://github.com/kriasoft/react-starter-kit https://github.com/kriasoft/react-starter-kit