Closed srcspider closed 9 years ago
I by large agree. Trying to fit the existing model into ES6 classes is ugly, and I really can't see what the real benefits are.
I think there's definitely a transition period until everything fits into place neatly and ESx catches up, but I think the vision behind the current direction is as sound as they come. Instead of using the vendor specific React.createClass
with vendor specific behaviors and features which does not interop with other libraries, why not use native classes?
Sure there's a lack of mixin-support in ES6, but there are ways around that. Property initializers are not here yet so that uglies it up a bit too and ES6 classes are not auto-bound which kind of sucks I guess, but property initializers will be the rescue there as well it seems. So yeah, using ES6 classes is still early perhaps, and if you choose to use them you are an early adopter in some way I would say. React.createClass
is still there.
But the great thing about using native classes? React.createClass
is now just one way of creating classes, if there's one you prefer more out there you're now free to use it and when native classes are ready in your eyes, you can slowly migrate away from whatever class helper you were using. React has no longer decided for you what is best for you, you're free to use whatever you want... that seems amazingly great if you ask me, I don't see the issue.
EDIT: In my words, React is moving in the direction away from unnecessary forced opinions and library bloat. React is not a class library, it's a view framework, so why should it be forcing a certain class library on you and X, Y and Z. React should focus only on what is the best future implementation, everything else the community can provide (or official addons if absolutely necessary), everyone has a different opinion on what is the right way, now everyone has the freedom to choose.
I wrote briefly about this: https://news.ycombinator.com/item?id=8959691
It's not about fashion, OOP, ES6 or classes, really.
As far as mixins I made react-mixin based on a non-react-specific smart-mixin library. As far as the usefulness of classes... it seems to just be aiming for less react specificness, for better or worse.
yeah, I'ma blame my previous comment on ignorance, obviously I did not read the post properly, this all looks great.
@syranide
I think there's definitely a transition period until everything fits into place neatly and ESx catches up, but I think the vision behind the current direction is as sound as they come. Instead of using the vendor specific React.createClass with vendor specific behaviors and features which does not interop with other libraries, why not use native classes?
Here's native "classes," no drawbacks, more compatibility then ES6 classes, no transprilers or other code mangling intermediary layers:
var React = require('react');
// Object.assign, or a combination of Object.assign and Object.create
// on first paramter, etc. How you compose different objects will vary
// depending on your needs. Any merge function from a popular library
// will also suffice
var merge = require('some_merge_function');
var HelloMessage = function () {
React.Component.apply(this, arguments);
};
HelloMessage.prototype = merge(React.Component.prototype, {
render: function () {
return <div>Hello {this.props.name}</div>;
}
});
You don't need @brigand library for this either, here's his example with vanilla javascript...
var React = require('react');
var merge = require('some_merge_function');
var SomeMixin = require('./mixins/Some');
var Foo = function () {
React.Component.apply(this, arguments);
};
Foo.prototype = merge(React.Component.prototype, SomeMixin, {
render: function () {
return <div/>;
}
});
Original react-mixin example for reference,
var reactMixin = require('react-mixin');
var someMixin = require('some-mixin');
class Foo extends React.Component {
render: function(){ return <div /> }
}
reactMixin(Foo.prototype, someMixin);
reactMixin(Foo.prototype, someOtherMixin);
@gaearon
The change is subtle and easy to misinterpret. It's not that React drank ES6 class kool-aid and we're now gonna use inheritance over composition.
@syranide
In my words, React is moving in the direction away from unnecessary forced opinions and library bloat. [...] React should focus only on what is the best future implementation, everything else the community can provide (or official addons if absolutely necessary), everyone has a different opinion on what is the right way, now everyone has the freedom to choose.
I'm sorry but I can't help but feel you're trying to forcefully push ES6, for the sake of ES6, on the pretext of "good intentions." There is no benefit whatsoever to ES6 at the moment, and if anything any ES6 integration should be a separate module not the other way round. I shouldn't have to deal with nonsense such "oh you have to mangle your entire codebase though our wonderful code-to-nonsense ES6-transpilers" both in the default react and any addons. Which is turning to be the case with this move.
I stand by my criticism that pushing this feature is useless both in that it removes useful functionality (until ES6 even has any mixin/composition support it should not even be considered), mangles syntax (having a more raw interface doesn't mean the interface has to be really dumb for the sake of "less lines of code") and is only serving people who are toying with ES6.
Based on the discussion here and elsewhere it seems the general move is to simply cater to only ES6 with everyone else as third class citizen, at best.
What you're claiming doesn't seem in line with what you're actually doing. eg. "[...] moving in the direction away from unnecessary forced opinions" ES6 classes are very much extremely forced opinionated change.
Here's native "classes," no drawbacks, more compatibility then ES6 classes, no transprilers or other code mangling intermediary layers:
Wait.. Are you saying this doesn't work in React 0.13? I almost certainly tried something similar and it did work.
is only serving people who are toying with ES
It's the opposite: this is more useful to people not using ES6, or even JS for that matter.
ClojureScript adepts find it very useful:
now Om doesn't have to jump hoops for custom initialization + cleaner FP API
It also makes React easier to consume from TypeScript (#2952), CoffeeScript (#2944).
I don't get why you're focusing on ES6 when there's nothing ES6-specific in this change at all. It's just about making createClass
optional instead of forcing it upon users. This change is better for long term and doesn't hurt in short term, so what is the problem?
@srcspider I feel like there's a misunderstanding here, before all you had was React.createClass
and now you can use that or any other library or native class implementation you like. I don't see the problem; if you don't like ES6 classes don't use them? They're just syntax sugar really anyway. Keep using React.createClass
if you prefer it?
You don't need @brigand library for this either, here's his example with vanilla javascript...
@srcspider as long as some_merge_function merges functions by ensuring both are called, and handles the left operand (usually a prototype) having non-enumerable properties (as is the case in es6 class methods, as of 4 days ago), and still merging them correctly. The extra errors are nice imo, but not required.
Thanks for all the feedback! It's good to know what the community is thinking. Some people love ES6 classes, others don't like them as much. Fortunately, React lets you choose which syntax you'd like to use.
As @syranide, @brigand, and @gaearon mentioned, the change makes React classes less react-specific and makes them more interoperable with other libraries (and even other languages/dialects). It also reduces the learning curve, since all javascript programmers will soon be familiar with ES6 classes and won't need to learn the special semantics of our magical React.createClass method.
Having said all that, we do use mixins internally, and are abundantly aware of their usefulness (We may see mixins return in ES7 classes). As others have mentioned, you're free to continue using React.createClass() if you prefer that style.
I'm going to close this issue, since it's not technically a bug.
One of the biggest pro's of React is that it's simple.
It doesn't do 100 things, it doesn't try to be overly complicated with how it does things. The docs aren't the greatest at explaining what it does under the api but fortunately it doesn't try to sprinkle too much magical fairy dust in your eyes with what it explains.
This however...
This is for the most part just syntactic acid
That's not code, that's a fashion statement.
It's less clear since you've butchered initial state and default props into this generic meaningless concept of "constructor". There's no point in doing both things at the same time there, it's much clearer to do them separate. Functions doing one thing makes for clearer code and easier to follow logic. Even when you see it a lot. You want easily scannable code, not "less code" since you'll fall in the trap of "less [readable] code" when you do that.
There's then the whole concept of this being a class. What's the gain in this? I never ever had to do instanceof with components. The case is ridiculously rare, if there is even a case.
On the other hand what I do a lot is mixins, besides the constructor there making everything unnecessarily awkward for mixins to "help" with properties and state, the whole class construct just says "no mixins, please create giant monolithic unmanageable class hierarchies"
I'll be blunt, classes have some uses but they're few, and most of their solutions (such as inheritance) are just extremely naive solutions asking you to create problems for yourself to give them meaning. In code they scale horribly into unmaintanable giant scrabble tree, are hard to mix together (usually involving over-complicated solutions that would not be necessary with out their inherent limitations), and are practically taboo in performance code/languages given their anti-hardware nature.
In practice, from a React component all I need in terms of composition is to be able to mix in functionality into it, so that I don't repeat code (when I don't want to repeat it for clarity reasons) and I can centralize code when I feel that is a worthwhile benefit. The whole concept of class was originally conceived for this purpose (along with multiple inheritance because being able to mix in just 1 thing is not that great). The concept has failed to achieve, largely due to being over engineered. No amount of languages copy/pasting said failure in the interest of pandering to simple minded programmers who've been spoonfed oo-gospel will change that. The current React way of doing it actually managed to achieved the goal of easy mixing/reuse of code quite well within the context of React. I don't see where the need to move to a system that's less cabable and even has more issues from just the fact it's being use come from... we might as well replace the keyword "class" there with "snakeoil" because that's just how useless it seems to be.