
Removing User Interface Complexity, or Why React is Awesome - jlongster
http://jlongster.com/Removing-User-Interface-Complexity,-or-Why-React-is-Awesome
======
tomdale
This is a really thoroughly researched post and jlongster has my gratitude for
writing it up.

I have two concerns with this approach. Take everything I say with a grain of
salt as one of the authors of Ember.js.

First, as described here and as actually implemented by Om, this eliminates
complexity by spamming the component with state change notifications via
requestAnimationFrame (rAF). That may be a fair tradeoff in the end, but I
would be nervous about building a large-scale app that relied on diffing
performance for every data-bound element fitting in rAF's 16ms window.

(I'll also mention that this puts a pretty firm cap on how you can use data
binding in your app, and it tends to mean that people just use binding from
the JavaScript -> DOM layer. One of the nicest things about Ember, IMO, is
that you can model your entire application, from the model layer all the way
up to the templates, with an FRP-like data flow.)

My second concern is that components libraries really don't do anything to
help you manage which components are on screen, and in a way that doesn't
break the URL. So many JavaScript apps feel broken because you can't share
them, you can't hit the back button, you can't hit refresh and not lose state,
etc. People think MVC is an application architecture, but in fact MVC is a
component architecture— your app is composed of many MVCs, all interacting
with each other. Without an abstraction to help you manage that (whether it's
something like Ember or something you've rolled yourself), it's easy for the
complexity of managing which components are on screen and what models they're
plugged into to spin quickly out of control. I have yet to see the source code
for any app that scales this approach out beyond simple demos, which I hope
changes because I would love to see how the rubber hits the pavement.

It's always interesting to see different approaches to this problem. I don't
think it's as revolutionary as many people want to make it out to be, but I've
never been opposed to borrowing good ideas liberally, either. Thanks again,
James!

~~~
swannodette
To clarify, Om does not "spam" state change notifications via
requestAnimationFrame - all rAF calls are batched. For example if a state
change occurs we schedule re-render via rAF. If another state change occurs we
will not call rAF since one is already queued. In fact no state changes can
queue another rAF until all changes in the current cycle have been completely
flushed.

~~~
tomdale
I guess this discussion hinges carefully on our relative definitions of
"spam." ;) What I mean to say is that, changes or not, the browser will be
invoking your diffing algorithm every 16ms.

~~~
DougBTX
Won't that only happen if a state change has been made? That is, the diffing
algorithm will only get invoked once every 16ms if the state changes faster
than once every 16ms.

~~~
tomdale
Nope, it calls it regardless of state change—that's the point, you eliminate
the challenge of determining when state has changed.

To quote TFA:

> A set method to change state could trigger a rerender (React has setState),
> but there's an even easier way to react to changes: continuously call
> renderComponent with requestAnimationFrame to repaint the UI, and only
> change the DOM when the component returns different content.

Edit:

I was mistaken about how Om works. I was under the impression that Om
scheduled a rAF every 16ms to check for state change. In fact, it only
schedules a rAF once the state changes.

However, this relies on being able to listen for state change from the
underlying model data. I was under the impression that one of the benefits of
Om/React was that you could use its data bindings with any JavaScript library,
even if it hadn't been instrumented for property observation. Instead, it
seems that with Om, you are limited to consuming data structures that
implement its state change notification interface.

~~~
jpfuentes2
Thanks for clearing up the confusion. Although, I think it's worth it for you
to edit your initial reply since it's the most upvoted comment so far.

Also, your comment, to me, shows there is still some confusion regarding Om's
internals:

> However, this relies on being able to listen for state change from the
> underlying model data. [...] Instead, it seems that with Om, you are limited
> to consuming data structures that implement its state change notification
> interface.

Actually, the interface used is ClojureScript's flavor of STM: you set your
app state, generally a hash-map, in an atom. When you mutate the app state via
`swap!` it is published to Om -> React -> render. This may seem like a
pedantic distinction, however, the key point is that you are required to use
an atom which controls app state mutation. You could also use strings and
vectors as your app state if you so choose.

~~~
Touche
Interfacing with an external js library that publishes changes would be
trivial though. Typically if you're building a ClojureScript app you're
building a ClojureScript app... which means using atoms.

------
rdtsc
As mostly an outsider to the web front end development, React.js is probably
the easiest one for me to understand among the typical "frameworks",
especially Angular and Ember.

After all the excitement about Angular for example, I went to learn about it
and just got lost with new concepts: DOM transclusion, scopes, services,
directives, ng-apps, controllers, dependency inversion and so on. I can use it
but need someone to hold my hand. It reminded me of Enterprise Java Beans.

But so far just learning how React is put together and looking at the
tutorials it seems like less of a framework and easier to understand
altogether. I suspect this might become the new way to build web applications.

Well anyway, don't take this too seriously, I as said, I am an outsider to
this.

~~~
camus2
> After all the excitement about Angular for example, I went to learn about it
> and just got lost with new concept DOM transclusion, scopes, services,
> directives, ng-apps, controllers, dependency inversion and so on. I can use
> it but need someone to hold my hand. It reminded me of Enterprise Java
> Beans.

AngularJS has a serious "naming" problem.

Most these concept are easily understood when explained the right away,what
AngularJS doc doesnt do. The only complicated thing to grasp is the digest
cycle. But anything else is trivials.It's nowhere near the complexity of Java
EE.

Scopes are easy,like any composite structure you have nodes with children and
parents ,what make scopes special is that they can inherit properties from
their parent scopes.

Directives are just custom html elements/attributes where you should do dom
manipulation,all other angularjs components should be free from any DOM
manipulation,Directives are the closest thing to react components.

Controllers represent the state of the view,when the data in a controller
changes, a view that exposes that data changes and vice et versa.

Services are dumb objects that can be shared between controllers and
dependency injection is the way one share these services. Controllers can
references services ,and services can reference other services. Services are
singletons

So there is nothing really complicated with all these concepts,just that the
doc sucks for some reason.

~~~
chc
As the famous quote goes, there are two hard things in computer science: cache
invalidation and naming things. When I first heard it, I thought it was a
joke; nowadays I feel like it's barely a simplification.

~~~
possibilistic
"And off by one errors".

------
etrinh
Not to distract from the topic, but jlongster's posts should be a case study
into how to make an effective demo/tutorial on the web. The side by side
code/demo format is very well done and should be the de facto way to do code +
demo. There have been so many times when I've been reading a tutorial and
click on a demo link that opens a new tab. This makes me completely lose
context as I switch back and forth between the tutorial and various demo
links.

For another example of a post that takes advantage of the dynamic nature of
the web page, check out jlongster's sweet.js tutorial[1]. It's a tutorial on
writing macros with JS that you can actually interact with (you can make
modifications to the example code snippets and see your macros expand on the
fly). Very cool.

[1]: [http://jlongster.com/Writing-Your-First-Sweet.js-
Macro](http://jlongster.com/Writing-Your-First-Sweet.js-Macro)

------
derwildemomo
As a recommendation to the author, it would make sense to show the
example/demo area the whole time, not only once I scroll down. It confused me.
A lot.

~~~
joshstrange
Agreed, I really like the demo area but it's a bit of a shock when it first
shows up.

~~~
jlongster
Heh, it's been mixed reactions. I will probably tweak the initial experience,
but will need some time because I can't leave it open on load because it
blocks the header.

~~~
outworlder
I thought it was nifty. The shocking aspect might just be the big layout
change. Perhaps a notification ("Check out the demo") so the user has to click
it to enable the side pane, and then its business as usual.

~~~
cnp
I liked the layout as well. One thing I would change would be to make the code
area wider than the demo area, as some of your lines wrap, where the demo area
rarely needs a line break.

------
malvosenior
For those that haven't tried it, David Nolen's Om for ClojureScript is an
excellent React framework.

[https://github.com/swannodette/om](https://github.com/swannodette/om)

I've not used vanilla React, but Om is certainly fantastic and apparently adds
a bunch of stuff that's not in the JS version.

Also, a web framework written by the guy that wrote most of the language
you're using? Win!

~~~
ThomasDeutsch
I would love to support a JS project that is something like a port of OM to
JS.

~~~
malvosenior
I understand that there are sometimes practical reasons for not being able to
use ClojureScript, but have you given it a go? It's really very, very nice
(much nicer than JS in pretty much every way).

* Immutable data (you can get some of this in JS with Nolen's Mori [http://swannodette.github.io/mori/](http://swannodette.github.io/mori/))

* Better functional programming than Underscore (map :mykey some-objects)

* Great syntax: homoiconicity, thrush operator, first class set, regex, map, vector syntax

* Macros!

* Use of cool frameworks: Om, core.async

* Same language as back-end if using Clojure

It was quite frankly intimidating to get started with it all as an ex-
Java/Obj-c/Python/JS dev but I could never go back.

~~~
cnp
I've been trying to move towards ClojureScript for a while, but there are so
few introductory resources out there that allow you to navigate between the
Clojure world and the JavaScript world in a way that makes sense to people who
come from JS backgrounds exclusively.

I wish OReileys would issue an expanded version of their Intro ClojureScript
book!

~~~
undershirt
I've been learning CLJS for a couple months. Here's a syntax guide and a list
of resources I've used: [https://github.com/shaunlebron/ClojureScript-Syntax-
in-15-mi...](https://github.com/shaunlebron/ClojureScript-Syntax-
in-15-minutes)

~~~
cnp
After browsing around, you're GitHub repo is a learning treasure. Thanks for
posting all of that stuff in such a clear way.

------
NathanKP
I really like the core concepts of React, especially the way it is designed to
help you organize your code into reusable components.

I think the key to making React take off is building a centralized repository
for components that are open source. Then building your webapp would be as
easy as importing the components you need:

    
    
         bower install react-navbar
         bower install react-signup-form
         bower install react-sso-signin-form
    

I think this is definitely the future of how front end web development will be
one day.

~~~
embwbam
So I have a word of caution. As someone else in the thread mentioned, React is
very intuitive for beginners. There's another framework I've used that was
also intuitive for beginners: Backbone. The reason why Backbone is inferior to
Angular and Ember is because it optimized for the beginner. Angular and Ember
are optimized for the experienced developer on a large code base.

Specific to your suggestion, which I think is awesome, is the idea of
composibility. The easiest kind of component to write is a large component
with lots of options, like jQuery plugins. This is the hardest kind of
component to use _outside of its intended use case_.

What makes Angular so good is that the core directives are all extremely
composable. They can be used all over the place without hacking.

To make your dream come true we as component authors must design carefully to
make smaller, more focused tools, rather than large components, because large
components are harder to adapt to applications outside their main use case.

~~~
vjeux
React has been designed to work in Facebook's codebase, to build large
features worked on by many experienced developers. The fact that it is
intuitive for beginners is a side-effect, not the primary objective.

~~~
pestaa
Don't forget that Facebook invested a what I would call inproportionally lot
in the PHP ecosystem primarily to let new employees pick up the pace as fast
as possible.

I wouldn't be surprised if React was kept intentionally newbie-friendly, too.

~~~
yazaddaruvala
While it isn't impossible for a complex library to become popular, I would be
very surprised if a library/framework wasn't kept intentionally "newbie-
friendly".

------
ufo
I experimented with React a bit but I was a bit bugged by how large it was.
The basic idea of rendering to a virtual DOM and having unidirectional data
flow is really simple but I had trouble actually diving in to React's source
code and seeing things under the hood (for example, I had to find a blog to
see how the diffing algorithm worked).

What are the other libraries out there that we can use for this virtual DOM
pattern right now? I only found mithril[1] that similarly does the template
rendering with Javascript but I still don't know how different to React it is
in the end? Is the diffing algorithm similar? Do they handle corner cases the
same (many attributes need to be treated specially when writing them to DOM)?

Simplifying it a bit: other than the virtual DOM, is the rest of React also
the best way to structure apps? What would the ideal "barebones" virtual DOM
library look like?

[1] [http://lhorie.github.io/mithril/](http://lhorie.github.io/mithril/)

~~~
Raynos
I have a similar frustration with React. The source code is very hard to read
our follow.

An ideal "barebones" virtual dom library looks like [https://github.com/Matt-
Esch/virtual-dom](https://github.com/Matt-Esch/virtual-dom) . The `virtual-
dom` module was build out of frustration with the readability of react source
code and is the minimal modular subset.

I've also built a small framework on top `virtual-dom` to add in essentials
like immutable state and event handling (
[https://github.com/Raynos/mercury](https://github.com/Raynos/mercury) ).
Whilst mercury might not be the best way to structure apps, it's an approach
that is getting me far and I'm drawing strong inspiration from FRP and FP
systems like Elm and om.

~~~
ufo
Is there a single-file version of virtual dom available for download? I am not
finding any instructions in the repo on how to build it. Also, why does it
have so many files in the first place?

~~~
Raynos
I opened this PR on virtual-dom ( [https://github.com/Matt-Esch/virtual-
dom/pull/67](https://github.com/Matt-Esch/virtual-dom/pull/67) ) to get a
single file version into the git repo.

It has many folders because the `vtree`, `vdom` and `h` are fundamentally
seperate concepts.

Again each one is seperated into it's own files, this allows you to just
require the `is-x` functions or the `diff` function alone without having to
depend on the entire implementation.

It's also easier to maintain code if it's not one big file.

There are plans to break vtree & vdom out

\- [https://github.com/Matt-Esch/vtree](https://github.com/Matt-Esch/vtree) \-
[https://github.com/Matt-Esch/vdom](https://github.com/Matt-Esch/vdom)

Note `vdom` is an implementation detail, we could also write `vcanvas` or
`vwebgl`

------
Flimm
Please don't break the back button (Firefox and Chrome).

In Firefox 29.0 on Ubuntu 14.04, the left sidebar with the text of the blog
disappears and is replaced with a white space. I do not experience this on
Chrome.

~~~
jlongster
I just tried it on Firefox 26 on OSX and could not replicate. It has worked
for everyone I've had test the page. The only thing that happens when you
press back is the animation to load the right demo. There might be something
buggy with how the CSS animation is using your graphics driver?

~~~
hashberry
Back button breaking on latest version of Chrome/Win7 here. Scrolling up and
down adds history.

~~~
jlongster
It adds history?? What is the URL changing to?

~~~
ben336
URL doesn't appear to change in chrome, but the back button just cycles
through the various demo screens after you've scrolled down for a while.

~~~
jlongster
Oh, that's because the demos are loaded in an iframe. Not sure what the best
solution is, but I'll think about it. Thanks.

~~~
ulisesrmzroche
Whoa there. An iFrame? Why?

------
roycehaynes
Great post. I recently started a project using reactjs, and I have nothing but
good things to say. The unidirectional data flow, the declarative nature, and
the virtual DOM makes it powerful and very easy to like.

The best resource is to follow the tutorial (link below). The tutorial
explains everything you may have a question about when comparing it to
Backbone, Angular, or Ember.

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

I also found the IRC channel to be very, very helpful.

The only downside is that you still have to rely on other tools to make a true
SPA like routing.

~~~
roycehaynes
I found this blog post to be very useful on how to leverage Backbone.Route
with Reactjs.

[https://medium.com/react-tutorials/c00be0cf1592](https://medium.com/react-
tutorials/c00be0cf1592)

------
adamors
Would you recommend using React instead of Angular for JS heavy areas of a
website that is built with a server side framework (like Rails, Django etc.)?

I developed a rather complex SPA with Angular recently and I cannot go back to
the ghetto that is jQuery when using server side rendering.

~~~
mercer
Based on my initial explorations using React with Rails, I'd say React might
even be _better_ when used with an existing server-side framework.

With React, you can basically store all you data (state) in the root component
(which could be the root of your entire page), and replace that with new state
without thinking too much about the DOM updates and view changes that result
from this.

This is perfect for a server-side framework, because such a framework by
definition _already_ renders everything whenever something changes (page
refresh). Without React, the framework does a bunch of things and finally
craps out objects that are transformed to HTML by the view (where the views
are as 'dumb' as possible). _With_ React, instead of rendering the object to
HTML, you just pass these objects, as JSON, to a React component (which could
be the whole page), and it figures out what needs updating. You don't have to
deal (as much) with client-side logic if you don't want to, and things will
still be performant.

This also significantly simplifies server-side rendering, to the point where
it might require only one extra call to render the component server side (the
handy renderComponentToString).

Of course, in practice it's often not quite that simple, but because of how
React operates, you can get pretty far with relying primarily on the server-
side framework and little logic on the React-side of things (plus you can
achieve the 'holy grail' of seamless server- and client-side rendering.

(apologies if I'm getting things wrong, by the way. I'm by no means an expert
on these matters and only just diving into React.)

~~~
rebelidealist
Can you please explain how to store data from the server on a "root
component"?

The data portion is the main reason I was looking at Angular.

Thank you.

~~~
mercer
If you keep it client-side: you turn the server-side data into json, then pass
that to the renderComponent function (in a script tag or whatnot). Inside your
component, you'd use this data in the getInitialState function to set the
state of this component (which could pretty much be the whole page).

Does that answer your question?

------
mrcwinn
Curious if anyone has experimented with Go+React - specifically rendering on
the server side as well. Similar to Rails / react_ujs (react-rails gem), seems
like you would need to provide Go with access to a v8 runtime and a FuncMap
helper in the template to call for the necessary component (JSX -> markup).
I've really enjoyed React and I've enjoyed Go in my spare time, but I still
find myself using npm for a lot of the, um, grunt work.

------
nostrademons
I think this post is missing something in its description of Web Components:
the fundamental difference between a JS-based framework like React and a Web
Components-based framework like Polymer is that the former takes JS objects as
primitives and the DOM as an implementation artifact, while the latter takes
the DOM as a primitive and JS as an implementation artifact. You cannot wrap
your head around Web Components and give both it and JS frameworks a fair
shake until you can make this mental shift in perspective fluently.

The line in the post where "You can't even do something as basic as that with
Web Components.":

    
    
      var MyToolbar = require('shared-components/toolbar');
    

In fact has a direct analogue with HTML imports:

    
    
      <link rel="import" href="shared-components/toolbar.html">
    

And that's key to understanding Web Components. The idea of the standard is
that you can now define your own custom HTML elements, and those elements
function exactly like the DOM elements that are built into the browser. This
is a key strategic point: they function exactly like the DOM elements that are
built into the browser because Google/Mozilla/Opera/et al _hope to build the
popular ones into the browser eventually_ , just like we've gotten <input
type=date> and <details>/<summary> based on common web usage patterns.

A number of the other code samples in the article also have direct analogues
in Polymer as well. For example, the App/Toolbar example halfway down the page
would be this:

    
    
      <polymer-element name="Toolbar" attributes="number">
        <template>
          <div>
            <button value="increment" on-click="{{increment}}">
            <button value="decrement" on-click="{{decrement}}">
          </div>
        </template>
        <script>
          Polymer('toolbar', {
            number: 0,
            increment: function() { this.number++; }
            decrement: function() { this.number--; }
          });
        </script>
      </polymer-element>
    
      <polymer-element name="App">
        <template>
          <div>
            <span>{{toolbar.number}}</span>
            <Toolbar number=0 id="toolbar"></Toolbar>
          </div>
        </template>
        <script>
          Polymer('App', {
            created: function() {
              this.toolbar = this.$.toolbar;
            }
          });
        </script>
      </polymer-element>
    

You can decide for yourself whether you like that or you like the Bloop
example more - my point with this post is to educate, not evangelize - but the
key point is that _you can define your own tags and elements just like regular
DOM elements_ , give them behavior with Javascript, make them "smart" through
data-binding so you don't have to manually wire up handlers, and then compose
them like you would compose a manual HTML fragment.

~~~
jlongster
The problem is that it doesn't scale complexity-wise. You miss a key point
with imports: A `<link>` imports something into the global scope. There's
always one global scope. In my example, I was able to rename Toolbar into
MyToolbar and use it in my scope. You lose so much using the DOM as primitive
and JS as artifact.

And the second you start doing conditional elements (like the tabbed example),
Web Components gets pretty complex. In React, it's just `if(shown) {
renderItem(); }`.

If you make HTML smart enough, sure, you don't have to manually wire up
anything. But then you're left with `x-if`, `x-ajax`, and so on tags. Why not
just use JavaScript?

~~~
spankalee
Using JavaScript is fine for things that need script, but ultimately, if I'm
building HTML, I'd rather do it in HTML. Put another way: HTML is a great DSL
for creating HTML.

As for scoping of imports, you do have a point there in theory, but in dealing
with quite a few complex Polymer applications at this point I haven't seen
that be an issue in practice. The scoping issue is well known among the people
working on Web Components, and AFIAK there are plans to address it.

I'm not sure why you think conditionals are complex in templates. Your example
might look like this in a Polymer template:

    
    
      <template if="{{ shown }}>
        <my-item></my-item>
      </template>
    

Yes, there's some token overhead, but in the context of a larger template it
pays off to have the entire HTML specified in one place, and in a way that
mirrors it's output structure, not spread out over often hard to follow
imperative code.

However, as you point out, Web Components doesn't prescribe how to manipulate
the DOM, so if you still prefer to do it in script, go ahead!

The point is to produce an element where the browser, developer tools, and
your users don't have to care what choice you made.

~~~
peterhunt
HTML is a great DSL for creating static HTML.

When you start to bolt on features for dynamism in HTML you end up with
Angular. The reason that it has all of those complex features is because it
needs them to build real world apps. I'm sure once people have built more
stuff with Polymer you'll start to see similar "feature creep".

~~~
spankalee
I've worked with a number of very complex Polymer applications, probably the
most complex Polymer applications in existence right now, and the template
features have been sufficient so far, and there's always the fallback to code
if necessary.

I can think of very few common feature requests (mostly on Shadow DOM,
actually), and they don't being to approach the complexity of Angular, which
concerns itself with so much more than templating. Angular's complexity is not
simply an unavoidable consequence of being used for real world apps - it's
just complex.

------
redOctober13
Just want to say thanks to jlongster and everyone who's commented on here; I
created an account just to say thanks. I'm an amateur web dev/designer trying
to figure out how to move beyond static web pages, and have read what would
probably amount to a literal ton of material were it printed out, on
frameworks, libraries, and more acronyms than I could imagine. Outside of
HTML, JS, and CSS, even "basic" things like Sass and CoffeeScript I hadn't
heard of just a few months ago, and I've since been all over the world (wide
web) looking for info on ASP.NET (which my group at work decided last year was
what we should be doing "web-kinda stuff" in, as well as Angular, Ember,
Backbone, Knockout, Node, etc etc, and everything new (to me) that research
like that comes with.

The discussion here has led me to a few more things to research, but I feel
it's been very helpful in helping me think critically about the vast array of
possibilities a budding web designer has to deal with. I just wanted somebody
to provide an objective view of "If you're going to be doing medium-complexity
web apps end-to-end, then learn ______" and I still would love that, but don't
think it's possible to get. The alternative, as I've been doing, is just to
learn a little about everything, try to figure out the kind of things I plan
to do, and then find the paradigm that works, be it vanilla technologies,
something like React, Web Components, or a framework (and I've been trying to
learn Angular and like it, but it's tough to grasp). It just seems like as
soon as I've decided on what I want to learn, I read a new post with a title
like "Why You Shouldn't Use <whatever I just decided to learn> and Why
<something new I've never heard of> Is Really the Way to Go."

So anyways, a long-winded thanks, but a thank you nevertheless for the open
discussion here; I feel better now that I'm not trying to find the one-and-
done "best" thing for making web apps in general.

------
zenojevski
For those who are only interested in the render loop, I made a library[1]
around this abstraction.

I plan to expand it with a toolkit to allow thinking in terms of batches,
queues and consumers, à la bacon.js[2].

[1]:
[https://github.com/zenoamaro/honeyloops](https://github.com/zenoamaro/honeyloops)
[2]:
[https://github.com/baconjs/bacon.js](https://github.com/baconjs/bacon.js)

------
jdnier
Leo Horie, author of Mithril, has written a blog post where he explains how to
re-implement some of the article's examples using Mithril (React-like client-
side Javascript MVC framework): [http://lhorie.github.io/mithril-blog/an-
exercise-in-awesomen...](http://lhorie.github.io/mithril-blog/an-exercise-in-
awesomeness.html)

~~~
jdnier
Mithril docs:
[http://lhorie.github.io/mithril/](http://lhorie.github.io/mithril/)

------
gooserock
I like the state and property features of React, but I still don't understand
why more people aren't using Chaplin instead. Because quite honestly, the
syntax of every other framework - React, Ember, and especially Angular - is
complete gobbledygook by comparison.

Example: in Chaplin, components are views or subviews (because it's still an
MVC framework, which is another discussion for another time). The views by
default render automatically without you having to call anything. But if you
did, you'd write @render() (because hey, Coffeescript saves keystrokes and
sanity). That automatically renders the component in the place you've already
specified as its container attribute, or if you haven't it renders to the body
by default.

Whereas in React, you have to write this garbage: Bloop.renderComponent(Box(),
document.body);

WHY. Can't we write a framework that intuits some of this crap? Shouldn't we
use a framework that reduces the time we spend writing code?

~~~
pestaa
Automatic rendering is fine in small projects. Seemingly random appearance of
widgets would, however, drive the debugging person crazy.

Comparing this.render to Bloop.renderComponent is superficial. If rendering
needs to have a handle on different resources, you'd either violate the
encapsulation in the former example, or write a service to couple them on a
separate layer -- that service might as well be called Bloop.

Some of this crap makes hard things possible.

------
1986v
If school books had online versions like this page, it would make reading so
much more fun.

Great read, by the way.

------
platz
I was at a meetup where the speaker suggested react is great for business-like
apps, but for things with an insane amount of dom objects like html games, it
tends to get bogged down.

Since React claims to be super fact, has done a performance comparison to see
in what situations and how much better react performs in certain cases,
compared to say, angular.js or more vanilla frameworks?

(Also I hear that there is a really great speedup that using OM gives you, but
I haven't seen any comparisons with om either)

~~~
camus2
if you are going to update the DOM 60 times per second no databinding/reactive
whatever framework makes sense.

there is so much overhead with these solutions performances would just be bad.

However it would be interesting to extract the virtual DOM from React to use
it in the context DOM based games, being able to mark elements as dirty in
order to redraw them is a usefull feature.One just doesnt need all the
JSX/databinindg stuff for a game driven by a gameloop.

~~~
spicyj
JSX is a build step and is completely optional. If by "databinding stuff" you
mean React's setState and friends, almost all of React's code deals with the
actual diffing and browser handling. Components are not much more than
functions from props to a virtual DOM output. It's easy to use React without
ever calling React.createClass (just pass the output of React.DOM to
renderComponent). Still, we're looking at separating these parts of React so
that you don't have to pay the file bytes but it's not a very significant
difference right now anyway.

~~~
camus2
thanks for the info, i'll try to hack something with React for my next DOM
based game and see if it works.

------
badman_ting
I recently watched a presentation about React's approach (I think from a
recent JSConf) and it sold me, at least enough to try. The approach makes
total sense to me, and I agree with many of its criticisms of Angular in
particular. I really loved the reconsidering of our idea of "separation of
concerns", that if we reconsider the scope of the concern, we can devise an
approach where templating and logic go together. I'm excited by these ideas.

~~~
davidgbeck
Seems like putting templates inside js is a step backwards. The advantage is
that you can package templates together with js? That problem is still
solvable while maintaining separation. For instaces with browserify tramsforms
you can just require( 'my-template' ).

[https://github.com/epeli/node-hbsfy](https://github.com/epeli/node-hbsfy)
[https://github.com/rotundasoftware/nunjucksify](https://github.com/rotundasoftware/nunjucksify)

------
IanDrake
Tester: The UI is wrong right here...

Developer: Hmm...I wonder how long it's going to take me to figure out where
that HTML was generated in my javascript.

~~~
Zelphyr
You hit the nail on the head why these things are bad.

You can either build something on a mass production line, where you're just
screwing the same bolt in day in and day out, or become a master craftsman and
build it with proper care, design, and quality.

These frameworks are nothing more than a factory floor and if all you do is
build apps with a framework you're little more than a paid glue stick piecing
bits of code together. Or you can become a master software developer and build
something of quality without needing a crutch like a framework.

Now, if the needs of the project are such that a framework will suffice then
by all means, use a framework. Chances are, if you're doing more than building
a working prototype then at some point a framework is _going_ to fail you. If
you enjoy building apps using frameworks then by all means, do it. But to my
mind you're doing your customer a disservice.

Contrast that with great software developers (and I've been fortunate to have
worked with some _really_ great developers) who abhor these frameworks. They
can get more done with less code and ultimately deliver the project faster
without frameworks. The tradeoff is that it takes time and dedication to
achieve that level of mastery. I personally would prefer that path.

~~~
aquark
Of course it really is frameworks all the way down. Unless maybe you're
building systems by laying out your own transitors.

The trick is to understand the strengths and weaknesses of any given framework
and match those with the constraints of your project.

~~~
Zelphyr
I disagree that its frameworks all the way down. There is a distinction
between frameworks and libraries. React, Angular, et al are frameworks in the
truest sense of the word.

Things like jQuery and Underscore on down to stdio.h are libraries. You can
pick and choose from what they contain but they're not so tightly coupled that
they get in your way.

They're a tool belt with tools that do one thing and do it really well.
Frameworks are like having a tool belt with a hammer that also has a saw on
the end but in order to use the saw you have to grab the screwdriver even if
you're not actually using it.

~~~
mercer
Thanks for pointing out the distinction. I forget about that sometimes.

That said, React is a "A Javascript Library for Building User Interfaces." And
to me me it _does_ feel more like a library than a framework.

------
valarauca1
It was really cool, until I realized that scrolling broke the back button.

I thought one of the cardinal sins of web design was don't break the back
button.

------
iamwil
Has anyone tried to use a different template engine with React? I was just
wondering, since I didn't want to use JSX inline, and writing out html with
React.DOM isn't appealing either.

I just wanted a way to put templates in <script> tags that get loaded by React
Components. That way, I won't be mixing templates and the behavior of the
components. Has anyone done this before?

~~~
cnp
There's this:
[https://github.com/mereskin/jsxify](https://github.com/mereskin/jsxify)

But really, once you get used to keeping everything together it _really does
feel better_. You just have to try it out.

Personally, since I use CoffeeScript, I like this lib:

[https://github.com/atom/reactionary](https://github.com/atom/reactionary)

which, since it strips out the required `null` or `{}` first parameter, feels
very much like haml or jade.

~~~
iamwil
I use coffeescript too, so I should be able to use reactionary to write the
dom helpers it exposes in my JSX. So then the coffeescript -> jsx on server
side, then jsx -> javascript browser side, is how it works, right?

I think I'm slowly being convinced putting it together in the same file makes
sense, since it's a single component, and the what's being displayed is
coupled with what you'd do with it, so I guess it should belong in the same
place?

~~~
cnp
Well, the way you should do it is abandon .jsx completely, and just stick to
.coffee.

Something like this:

React.createClass

    
    
       render: ->
     
          {div, h1, span} = require 'reactionary'
    
          div class: 'home',
    
              h1 "Hows it going!"
    

Clean and simple, particularly with CoffeeScripts default return.

As far as templates go -- and this is what I always tell people -- structure
your code in a clean way which makes the render function pop out and you might
as well be working with a separate file! It really does make more sense after
a while.

~~~
iamwil
Cool, I'll give it a shot.

I checked out reactionary, why couldn't I just do:

{div, h1, span} = React.DOM?

------
mushishi
The awkward right panel that changed abruptly from time to time, especially
the first transition, made me skip the content.

Using a non-common ui idiom is risky. The presentation and topic don't match
in a way that reader (i.e. me) had enough expectations left when it comes to
what you might actually have to say.

~~~
mmabbq
I feel kinda bad that you're being downvoted. I also felt the presentation was
a little jarring. The right panel seemed to change at strange times related to
the content I was reading. Perhaps it was an overuse of the "change things
while the user is scrolling to make it seem cool" theme I've been seeing a
lot.

On the other hand, I actually found the content pretty great, but I'm not a
web developer so take that with a grain of salt...

------
zawaideh
Instead of having React altogether, wouldn't it make sense to have the browser
keep track of a virtual DOM, and only repaint whatever changes on its own,
while managing its own requestAnimationFrame and paint cycles?

P.S. I haven't looked into this in depth, just throwing an idea out there.

~~~
rdtsc
Yeah if the technology was in the browser that would possible.

From what I understand, the core idea is that changes are applied to the
virtual DOM in a very simple way (from the application point of view). Then
there is another piece of code that knows how to efficiently find the diff
between the vDOM and DOM and apply the changes. It seems that last part could
be done by the browser.

~~~
stuki
The additional layer of redirection, at least conceptually enables the use of
application specific, or pluggable, vDOMs and/or diffing strategies.

------
__david__
So I'm curious how one would implement something like drag and drop in a React
app?

Would you model the drag in the main data model somehow? Or would you do that
all externally (with traditional DOM manipulation) and then update the model
when the drag is complete?

~~~
cnp
The latter. You would use html5's draggable, then update on complete.

Check out [http://webcloud.se/sortable-list-component-react-
js/](http://webcloud.se/sortable-list-component-react-js/)

------
cellis
Needs a catchy buzzword. So, can we all agree to name this ... NoHTML?

------
cnp
This is definitely a "Sell this to your boss" type of post :) Great work.

------
ulisesrmzroche
I'm honestly really, really wary of minimalistic front-end frameworks after
two years of working on single page web apps.

All that ends up happening in practice is untested, messy code with deadlines
up your ass and 0 developer ergonomics. Zero.

~~~
dangoor
It's hard to say what, exactly, you're referring to here. React, in many ways,
is not so much a framework but rather a really smart template system. It's
ergonomics, I've found, are quite nice.

------
outworlder
I was half-expecting a gambit Scheme post :)

------
mattdeboard
This is great except the button is broken.

------
gcb0
my gripe with those is that you remove UI complexity but shove usability and
accessibility over some dark orifice.

All those things are cool for social apps (a.k.a. fart apps) but for business
ready platforms this is just silly.

for example, a link that i can middle click or bookmark or send to someone,
etc would be much more useful even if not as spiffy as those scrolls

------
__abc
back button behavior is atrocious ....

~~~
alttab
But Javascript is awesome! Its the future.

~~~
Zelphyr
Javascript doesn't inherently break the back button. Sloppy developers do.

~~~
alttab
Certainly, but sloppy developers using Javascript makes it way easier to break
the back button than server-side rendering.

~~~
modarts
You can break the living hell out of the back button with server-centric
solutions (hello asp.net, and POST's for everything)

~~~
alttab
Fair point. I feel like us server folk have figured that part out by now at
least, the Javascript stuff is still quite the wild west on the client.

------
jbeja
I hate OP website, why i got to click the back button 10 times to comeback
here?

------
jafaku
Damn, Javascript is only becoming messier. I think I'll just watch it from the
distance and wait until someone figures out the best way to deal with it.

~~~
Rygu
That might take a few browser generations sadly. HTML6 anyone?

edit: HTML/next apparently:
[http://www.w3.org/wiki/HTML/next](http://www.w3.org/wiki/HTML/next)

