
React v0.12 - spicyj
http://facebook.github.io/react/blog/2014/10/28/react-v0.12.html
======
jbhatab
I don't know if I'm reading the changes wrong, but I'm not liking how I have
to do an extra step if I don't use jsx. I want to use coffescript and not have
to do extra stuff.

I definitely feel this forced vibe around making everyone use jsx, but have
yet to hear any compelling reasons why it's better.

~~~
sebmarkbage
Hi, this was a tough call for us to make. We wanted to everything we could to
avoid extra bloat for everyone. In the end, most people tend to use some kind
of extra helper, even if it's not JSX. E.g. a custom library or another third
party language.

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.

~~~
jbhatab
Thanks for the response.

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?

~~~
sebmarkbage
In CoffeeScript it might look something like this:

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.

~~~
kaoD
I guessed that indentation:

    
    
        element =
          type: 'div'
          props: className: 'container'
          children: [
              type: 'span'
              props: className: 'foo'
          ,
              type: CustomClass
              props: className: 'bar' 
          ]

------
simplify
I'm disappointed that JSX is now so coupled to React. I was looking forward to
JSX being used by many different JavaScript frameworks[1], but this change
reveals the devs are not interested in moving that direction.

[1] Example: [https://github.com/mrsweaters/mithril-
rails](https://github.com/mrsweaters/mithril-rails)

~~~
spicyj
We do actually want JSX to be flexible and usable for not just React, which is
why we're trying to write a formal specification of the syntax with multiple
parser implementations:

[http://facebook.github.io/jsx/](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.

~~~
simplify
A specification is great, and I'm happy to see that. However, even though it's
true that transpilers can compile JSX with arbitrary semantics, it still
requires _writing your own transpiler_.

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 =/

~~~
malandrew

        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.

------
malandrew
What options are there for syncing flux stores on the server and client?

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).

~~~
collyw
That sounds like a problem of pushing too much processing to the client side.

~~~
collyw
A downvote for pointing that out.

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.

------
jaredgrippe
I have a huge problem with this change explained here:
[https://gist.github.com/deadlyicon/da8c020662ea8e6002dc](https://gist.github.com/deadlyicon/da8c020662ea8e6002dc)

~~~
chenglou
Rest assured, see sebmarkbage's and my reply here:

[https://news.ycombinator.com/item?id=8523732](https://news.ycombinator.com/item?id=8523732)

[https://news.ycombinator.com/item?id=8524465](https://news.ycombinator.com/item?id=8524465)

~~~
jaredgrippe
The object literal syntax also sucks :(

[https://gist.github.com/deadlyicon/79c09610cac5a67f4a5d](https://gist.github.com/deadlyicon/79c09610cac5a67f4a5d)

~~~
spion
Agreed.

* 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?

~~~
peterhunt
If you wrap the class in createFactory() then you break instanceof; how is
this fine?

~~~
spion
True. But I can't come up with an example where I'd use instanceof on react
components, can you give me one?

~~~
mateuszf
Just wondering .. maybe it's used internally by the library?

------
palcu
A sincere and big thank you for building and evolving this awesome tool that
simplified UI madness in browsers. :-)

------
hardwaresofton
As a person who is using react, this is a welcome change! I'm glad they're
taking time to get rid of the kludgy code that wasn't quite consistent.

~~~
jbhatab
Hey can you explain how they improved consistency because I just don't
understand how the new changes help. I may just not understand what they did
at a fundamental level.

~~~
hardwaresofton
IMHO it's more consistent because the things that react has been modifying
have been Elements all along (DOM Elements).

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

------
glittershark
Always really happy to see a ton of breaking changes in a pre-1.0 release, and
very pleased that they're all moving towards simplifying the public API.

------
xiaoma
Ouch. I've been building dynamic components using transferPropsTo(), which is
now deprecated. It's very flexible and working well, so I'm a bit bummed to
see it go.

    
    
      render: function() {
        // after building up some object, propsObj that is determined by state
    
        return this.transferPropsTo(
          Component(propsObj)
        );
      }

~~~
lobster_johnson
No problem, just do this instead:

    
    
      render: function() {
        // Assign propsObj here
    
        return <Component {...propsObj}/>;
      }

------
fiatjaf
I don't get the React.isValidComponent -> React.isValidElement change. Wasn't
"class" the name of the abstract idea of component and "component" the name of
the actually rendered component, the class materialized in a DOM?

~~~
spicyj
See this post for a description of our terminology:

[http://facebook.github.io/react/blog/2014/10/14/introducing-...](http://facebook.github.io/react/blog/2014/10/14/introducing-
react-elements.html)

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.

------
jaredgrippe
One of my favorite patterns in React is using functions to wrap a React
component.

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?

~~~
sebmarkbage
This is actually an anti-pattern that we're explicitly trying to get rid of.
The fewer components you have, the fewer optimization hooks you have. This
also have subtle changes in semantics, and disables local optimizations in the
consuming files.

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...](https://github.com/reactjs/react-
future/blob/master/01%20-%20Core/03%20-%20Stateless%20Functions.js)

------
josebalius
So are ES6 classes for components coming in 0.13?

~~~
lobster_johnson
You can use ES6 classes today:

    
    
        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.

------
bostonvaulter2
I've been looking into React.js recently and I have a general question. Is it
possible to use React.js with zurb foundation cleanly? It appears that it will
not work well because Foundation expects to modify the state of the DOM for
Foundation elements. Are there any workarounds?

~~~
biscarch
After looking into this I've come to the conclusion that rewriting the
JavaScript to handle events through React's system is the best way to include
Foundation's JS components. (This is something I'm planning to do with
Foundation-for-Apps since I won't be using Angular).

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.

------
moondowner
The license change paragraph mentions patents. Anyone knows which Facebook
patents are used in React?

------
Kiro
How are bindings in React not two-way? Update an input field and it updates
the underlying JS object. Update the object and it updates the input field. I
thought that was the definition of two-way, regardless of what happens behind
the scenes.

~~~
insin
It doesn't update the underlying object for you by default.

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.

[http://facebook.github.io/react/docs/forms.html](http://facebook.github.io/react/docs/forms.html)

------
limsup
Can someone explain what the "spread operator" is and how to use it?

~~~
jbaudanza
[https://gist.github.com/sebmarkbage/07bbe37bc42b6d4aef81](https://gist.github.com/sebmarkbage/07bbe37bc42b6d4aef81)

~~~
claar
Wow, the example in that gist:

    
    
      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.

------
scwoodal
Are the v0.11 docs available anywhere other than the Github markdown files?

------
johne20
off topic a bit, but why do the CDN urls 301 redirect?

~~~
zpao
Mostly what @BinaryBullet said. fb.me is a urlshortener and then it hits real
CDNed files. I (as maintainer of React) suggest not actually using fb.me urls
in production. Use cdnjs or jsdelivr. Or host it yourself. We've been meaning
to put together a proper CDN hosting setup for JS libraries but just haven't
gotten around to it.

~~~
johne20
Out of curiosity why don't you suggest using the fb.me urls in production? It
would be nice to take advantage of the reach of Facebook to know that a decent
percentage of users would have hit the CDN'ed react url before hitting non-fb
site(s).

------
fiatjaf
I really don't see the point of making so much breaking changes just to
simplify the public API. The thing was working, it was good. It didn't need
any changes. God would have rested.

But well, the developers were there and, you know, they cannot see a
repository without commits for much time, right?

~~~
spicyj
We made these changes to try to make React better for everyone, but if you
would like to continue using React 0.11, please do.

~~~
fiatjaf
Please, don't take this as an offense. I didn't mean to. This was an attempt
of a joke, but it clearly didn't come out the way I wanted.

I love React, I love you guys for making React and I'm sorry for this comment.

