React v0.12
facebook.github.io
facebook.github.io
I definitely feel this forced vibe around making everyone use jsx, but have yet to hear any compelling reasons why it's better.
It's not a huge deal, but I keep getting this sense that jsx is strongly tied to react and this reaffirms that they are going to keep it that way. I do trust the react team still, but it makes me weary of future releases.
In short, this is somewhat of a transition step for the (imo) even better way of specifying your render with pure vanilla js collections. This goes in the opposite direction of what you're worried about. You can view `createElement/Factory` as the stepping stone, with the _additional_ benefit of allowing you to use es6 classes very soon. Smaller API surface and + using more js features rather than library-specific ones; what's not to like? =)
As for your worries about JSX: yes, it does come from React since the beginning. But we've taken an extra step of making it clear that this doesn't have to be React-specific: http://facebook.github.io/jsx/. You can plug this in CoffeeScript. If not, see my previous point.
As long as we can always do something like
div className: 'foo',
span className: 'bar'
Custom className: 'baz'
I think we'll be reasonably happy. But nobody likes feeling like a second-class citizen =)http://facebook.github.io/react/blog/2014/10/14/introducing-...
One reason for this change is to make it possible to use object literals or record syntax where that is more appropriate than function calls. We don't currently recommend it because there's no validation in that case, so you probably want static analysis to catch errors. I would encourage you to play with the idea of using object literals instead of function calls though.
One compelling reason for this change is that in 0.13 you will be able to build components using plain CoffeeScript classes instead of relying on React.createClass. So, in the end, you will be getting some of that bloat/overhead back.
We're definitely not making React depend on JSX. We will continue to support non-JSX and fully support compile-to-JS languages. Unfortunately, that sometimes means a trade-off. In this case trading React.createClass for React.createFactory. Some would've preferred it be the opposite tradeoff but React.createFactory gives us more benefits than the opposite.
Could you give me a quick example of calling a component with object literals instead of functions? I'm not understanding how that will play out in the final code.
Also, isn't it just adding React.createFactory, not replacing React.createClass?
element = type: 'div' props: className: 'container', children: [ type: 'span', props: className: 'foo' type: CustomClass, props: className: 'bar' ]
(This doesn't fully work in 0.12 because we also have some extra properties on there but that's the direction we're going.)
0.12 is just adding React.createFactory. 0.13 will optionally replace React.createClass.
We do this so that there's a seamless upgrade path. We have to remove the warnings to fix the classes.
element =
type: 'div'
props: className: 'container'
children: [
type: 'span'
props: className: 'foo'
,
type: CustomClass
props: className: 'bar'
]I will say that I do really like the syntax of coffeescript as is though,
div className: 'container',
span className: 'foo'
CustomClass classname: 'bar'
It reminds me a lot of slim and reads nicely.I can't decode what "Composite Component functions can no longer be called directly" means exactly in terms of code that will no longer work.
I definitely use React without JSX in plain JavaScript and I really love it. I'm kind of dreading what this little snippet means when I try to update to 0.13.
I think this will be the most revolutionary aspect in the next months, both for development and tests. I wrote an article explaining why I have this opinion:
https://gcanti.github.io/2014/10/29/understanding-react-and-...
It still doesn't solve the stuff JSX has for splats though ...
[1]: https://gist.github.com/mikew/e737273e42ed704c6c54#file-zz-r...
[1] Example: https://github.com/mrsweaters/mithril-rails
http://facebook.github.io/jsx/
We intentionally don't specify semantics to give different transpilers the flexibility to compile the JSX into whatever's appropriate for the library you're using.
It's possible that this will eventually unify again. E.g. around a replacement for an object literal. E.g. a standard record type.
JSX is a great syntax, and these changes mean nothing if you're a transpiler writer. What I was hoping for was the JSX transpiler that React uses would become flexible enough for any library to use, without the need to modify/rewrite the transpiler itself.
Yes it's possible for someone else to write something like this, but writing a compiler is no small feat =/
JSX is a great syntax
It's really not. It's just mixing syntaxes to solve the problem that mixed syntaxes causes. Higher order functions (i.e. createFactory) is a much better solution.I don't care if JSX is this or that, I simply have no interest in using or learning it because its not significant enough nor applicable outside of your framework and enforces anyone else who I work with to also adopt it.
This isn't just my opinion, having discussed using React this was the general consensus in a team of very different people, I stated that its fine because you don'e need to use JSX ... but at the moment it looks like you are focusing on moving developers in the direction we don't want to go.
I'm not sure if it's yet been updated to support createFactory, but even if it doesn't you could create a simple higher order function the partially applies the static unchanging DOM parts, returning a function that takes the same data type as the function returned by createFactory.
IMHO, with createFactory, there is no longer a good justification for JSX. JSX basically solves a problem that JSX created. The reason people like JSX is that it takes the unchanging DOM structure (basically the virtual DOM equivalent of HTML templating) and puts it in HTML like templates do. This gives it a sufficiently different syntax, that it's easy to visually discern the changing parts from the unchanging parts, especially with syntax highlighting support. However, with createFactory, you have a way to wrap up all the unchanging structure, such that you don't have to constantly have to mentally parse the unchanging structure from the virtual DOM that render() is actually going to update. This means you still have to deal with React.DOM, but if you use react-hyperscript, the syntax is sufficiently simplified that it's comparable to HTML.
The complexity of JSX simply isn't worth it. It breaks too many tools.
I ask this because the increasing move towards microservices seems to suggest that "joins" are going to start taking place on the client via waitFor.
For example, if I get model A and it depends on Models B, C and D. I don't want to have to wait for the client to fetch model A before it knows it needs to fetch models, B, C and D. Ideally, as model A passes through the server side store layer, it already starts fetching models B, C and D so it has those ready to serve to client, (or better yet it anticipates that the client is going to want B, C and D and eagerly sends that data to the client).
Can someone explain why I would want to do joins on the client side, when there is mature, well tested, well understood technology for doing joins on the server side? All the data is going to be on the server, so no danger of loosing a connection.
* JSX more tightly coupled,
* less straightforward JSX->JS mapping - I used to be so excited to tell people how JSX simply maps to function calls in JS... well, now it generates boilerplate instead.
* worse non-JSX syntax
I don't buy the ES6/CS/TS argument - wrapping classes with createFactory before exporting seems fine to me, and I use typescript. Also, from what I can see the object literal syntax is always worse.
So its basically all about Jest. The only reason I see is that a mocking tool can't handle factories. Makes me a bit sad. Seems like a good example of "test induced design damage" to me. How about adding plugins to that mocking tool instead?
But the change in JSX seems to be just for Jest. JSX could still compile to function calls and stay completely decoupled from React. A new function `createFactory` would be introduced that takes a class argument and produces a factory, making ES6, CS and TS users pleased. No backward-compatibility breakage would be introduced.
edit: removed a non-constructive paragraph. Will play around with the new version more before commenting further. Hopefully I'll understand why JSX is a lot more complicated than it used to be :/
React called them components, and it's always felt like a kludge to create some thing that WAS a DOM element (boiling down to React.DOM), and then set it's "tagname" as an after-thought.
Things like prop are tied directly to the DOM Element, further suggesting that the "thing" the component was, was actually a DOM Element.
I guess it's really subjective, but I think it'll be clearer to explain to people now:
"React manages creation and rendering of dynamic/intelligent (DOM) Elements"
(bonus points for no overlap with the Web Components terminology)
But then again a lot of this is just my opinion, consistency
render: function() {
// after building up some object, propsObj that is determined by state
return this.transferPropsTo(
Component(propsObj)
);
} render: function() {
// Assign propsObj here
return <Component {...propsObj}/>;
}http://facebook.github.io/react/blog/2014/10/14/introducing-...
If I write
var C = React.createClass(...);
var e = <C />;
var c = React.render(e, document.body);
then C is a class, e is an element (previously "descriptor"), and c is the actual mounted component. Components are generally accessible only through "this", refs, and the return value of React.render.It goes something like this:
App.Button = React.createClass({
render: function(){
var className = 'btn '+this.props.className
<a href className={className}>{this.props.children}</a>
}
});
App.BigButton = function(props){
props = props || {};
props.className = 'btn-large '+props.className
return App.Button.apply(null, arguments)
};
How would you do something like this? var BigButton = React.createClass({
render: function() {
return (
<Button
{...this.props}
className={'btn-large ' + this.props.className} />
);
}
});
(Before React 0.12 introduced the JSX spread syntax, this was handled by transferPropsTo.)The idea of a lightweight declaration of a component (e.g. a just function) is definitely still on the table and might be resurrected in a different form.
https://github.com/reactjs/react-future/blob/master/01%20-%2...
class Button {
render() {
return <button>{this.props.label}</button>;
}
}
Button = React.createClass(Button.prototype);
Of course, it would have been nice to be able to skip that last line, and extend/mix in some React base class instead.That said, the styles are still usable without modification and you could tell React to not handle pieces of the DOM in some cases for the existing JS.
If you use an uncontrolled component (by giving it a defaultValue/defaultChecked prop) you have to pick up the new value using an event or directly via the DOM. If you do it this way, you can't update the displayed value by changing the props passed to it.
If you use a controlled component (by giving it a value/checked prop), its displayed value won't update unless you pick up the new value from an event and set it in whichever JS object you have holding its state for the next render. There's a helper for doing that, or it's easy enough to roll your own event handler which takes care of all your fields.
Instead of this:
var mapArgs = function() {
var args = Array.prototype.slice.call(arguments, 0, arguments.length - 1);
var mapper = Array.prototype.slice.call(arguments, arguments.length - 1);
return args.map(mapper);
};
You can do this: var mapArgs = function(...args, mapper) {
return args.map(mapper);
};
And you can also use it to apply. Instead of: var max = Math.max.apply(null, [1, 2, 3, 4]);
You can do: var max = Math.max(...[1, 2, 3, 4]); var component = <Component {...props} foo={'override'} />;
Wha?? For me, there's a point in a language where the benefits of syntactic sugar are outweighed by readability concerns.http://stackoverflow.com/questions/2856059/passing-an-array-...
http://stackoverflow.com/questions/1316371/converting-a-java...
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
I'm still learning more about JS and so I'm no expert, but it seems to be similar in concept to use the ... in other languages. I think Groovy has something similar and Java has the varargs. They have obvious differences, but conceptually I think of it as passing in a variable number of args.
But well, the developers were there and, you know, they cannot see a repository without commits for much time, right?
https://facebook.github.io/react/blog/2014/10/14/introducing...
I love React, I love you guys for making React and I'm sorry for this comment.