Hacker News new | past | comments | ask | show | jobs | submit login
The Case for React.js and ClojureScript (murilopereira.com)
200 points by mpereira on May 5, 2014 | hide | past | favorite | 85 comments

Almost everything I've seen about React makes me happy. However there are some parts for which I do not understand everyone else's excitement. This presentation contains a great example on slide 53 when it says:

"No Templates!"

With an exclamation mark, even! What it doesn't tell me, is what is wrong with templates in the first place? I happen to like them versus the feeling the alternative gives: Awkwardly-mixed-paradigms and using string concatenation while attempting to represent one language within another.

Can someone who dislikes templates explain? Or maybe explain what a template means to you, as perhaps we're not all thinking about the same thing when someone says "No Templates!"

I agree very strongly, but I can understand the opposite viewpoint.

For me, I like to write HTML in HTML. While I'm primarily a backend programmer these days, I've spend a considerable portion of my career writing HTML, so I'm very familiar and fluent in it.

As such, to me, writing HTML as HTML with annotations for data bindings and loop is a much better approach. Anything else just gets in the way of my workflow. AngularJS is the only tool I've used so far that really nails this properly. (At least since Zope)

However a lot of developers aren't HTML guys. They think in code, and to them HTML == DOM == a Tree structure. So it makes sense for them to be returning a tree.

I quite religiously think the latter is the wrong approach and results in less maintainable code. Instead of having a single template with the entire page clearly laid out, you end up with small snippets of HTML rendered all over the place.

This becomes even more jarring when you're working with designers that aren't coders. I manage a team of 7, and Using HTML-based templates means that my designer can write fluent AngularJS templates without developers having to do a thing. The alternative is for the designer to mock something up, and then for developers to cut it up into tiny little pieces and rewrite it in whatever DOM abstraction is the flavour of the month. Try reskinning a site made up of hundreds of small snippets of DOM vs a few complete HTML templates - the latter is far easier.

Some developers like to write Dom in Javascript because they know Javascript and don't want to learn another language.

To me, the idea that templates are bad because somebody doesn't want to learn another language just reeks of anti intellectual bullshit. Angular template aren't difficult.

I'll finish off this post by adding that I much prefer reactive code over imperative observables or dirty-checking, but Angular templates work so ridiculously well it'd feel like a step backwards moving to another framework that didn't have them. My dream toolchain would use something similar to Angular templates, with FRP code behind the scenes.

tl;dr To somebody used to writing HTML, building a page by emitting snippets of DOM inside Javascript is about as annoying as trying to write Javascript by emitting snippets of code in XML.

Have you looked at JSX[1] yet? Because I feel it was invented exactly to address your tl;dr - you're writing something that is very close to HTML inside your Javascript, so it definitely seems easier than writing JS snippets in XML.

Also, although I've found that ReactJS tends to encourage a more modular component structure (which I'm personally a fan of), there's nothing stopping you from laying out large chunks of a template instead of small snippets.

[1] http://facebook.github.io/react/jsx-compiler.html

Yep - JSX solves many of those complaints. (My post was more of a reaction to the 'templates are bad' tone than React itself). I'm not a fan of JSX as a templating language, but it's good enough.

I still feel that React encourages a style of development that pushes small snippets of HTML rather than full-page templates. Depending on your development style and the type of application your building, this may or may not be desirable. (If you're building something that's inherently component based, then it's good. If you're building something that's not, then it just adds boilerplate).

I'm working on a pretty large Angular project at the moment - it's been utterly fantastic, although it does have its warts. (Primarily around maintaining state ). React.JS claims to solve many of these issues, although I'm not entirely sure it solves them in the right way. (I'd prefer to aim for a more FRP approach personally).

I think the argument React.js and other component-based frameworks like Polymer and Brick are pushing is that you should always be building your application out of self-contained components that have a defined a defined set of inputs. They would argue (and I would agree with them) that "building something that's not" is a code smell.

This (in theory) helps code maintainability. The challenge then becomes designing components in such a way that code paths do not need to cross lines between these things.

I'd agree, except that I consider the level of granularity to be too fine the way React does it, resulting in too much boilerplate to do simple things.

I still feel that React encourages a style of development that pushes small snippets of HTML rather than full-page templates.

I work with Django currently. For dynamic content, in order to avoid repetition, we use includes and template inheritance. So that goes in the direction of small snippets rather than full-page templates. Do you not have to do anything similar with your angular templates?

Angular has directives, which are used to make encapsulated reusable components.

First up - React.js components are substantially better than Angular directives for this purpose, but the design of applications in Angular are generally not broken up into directives the same way you would use components in React.

In React, something as simple as a basic todo has a parent component, embedding another component for each row. In Angular, you would just iterate over your model.

Depending on your use case, having the whole thing as one snippet of straight up HTML with an ng:repeat annotation might be far more maintainable than breaking it up into parent and child components for such a simple use case, since you can get a full cohesive view of the code generating that part of the page.

Don't forget inclusion_tags. They are really poorly named though, they would have been much more popular had they been called "components".

The primary difference between an inclusion_tag and an include is that with an inclusion_tag, you can define the interface of your component with much more granularity. By default, each inclusion_tag is passed an empty context, whereas an include accesses all the data in the current context. This way, an inclusion_tag provides a much better isolation.

One other advantage is, this way, if you need to include some Python logic, you don't need to do all in a single view function. So, assume that your view function responds with a page with 5 components in it. If you follow the include path, all the data preparation goes into the view. With inclusion_tag, you can basically drop to Python at any level. For example, let's say you are viewing a list of questions and answers. Views do not allow you to attach Python code at the question or answer level. You can do it, but you have to traverse inside the data for the whole feed. With an inclusion tag, you can "attach" to the processing at the question or answer level.

For Angular folks, an inclusion_tag is very much similar to an angular controller. The primary difference there is again by default, Angular components inherit all the scope (similar to JS scope or Django's include scope), whereas react by default does not pass any variables, you need to pass them explicitly as props to the children (in angular, you need to add some information at the "directive" level to achieve this level of isolation).

One alternative for keeping the scope clean while using include is to use the "only" flag though, so if you are not going to do any data processing, that is easier.

That said, the use of inclusion_tags is a bit cumbersome, and I'm not making much use of it lately since I have switched to react.js and basically building my components in JS instead.

Take a look at this repository (start from the oldest commit) to see the workflow. It is pretty straightforward for designers.



Have you seen Rethinking Best Practices video[1] from JSConf?

I think it explains the point.

[1]: http://www.youtube.com/watch?feature=player_embedded&v=x7cQ3...

Wow, that was a great talk. I really didn't like React and didn't get why they've decided to mix concerns but I think I've understood their design decisions now.

I think I'll go give it another try sometime soon.

I have not. I will watch it soon and see if it changes my opinion.

And I recognize it is just that: an opinion. A habit developed over time. But as a result, after all these years, I am also familiar with its advantages.

The idea of "Data comes from X, gets passed to Y, and combined into a display", where "Y" gets stored in its own file somewhere, can be reused everywhere, and decoupled from whatever is passing it the data that will be displayed within.

The general premise is that in practice templates usually end up very tightly bound to the view using the template, so you're not actually gaining anything by putting them in a different file and there's a lot of downsides to using a different language for templating.

Having watched the talk now, I see what he's getting at. I have maintained, at most, a small-approaching-medium-sized single-page app, and it was an internal tool. Clearly I have not felt any of the same pain that inspired React.

But within that particular experience, despite my "underpowered" templating tools, I've settled on a style that very close to what he calls "components", built instead from pairs of one partial and one viewmodel. Tightly coupled (cohesive?) within each pair, but as a unit are reusable together elsewhere in the front-end app.

So I can agree in theory, and see where my ideas have wandered close to the path that React takes. Really the only thing to do now is try it on a substantial project to see how it compares in experience. I suspect I'll still feel the urge to want the JSX in a separate file in some cases.

> and using string concatenation

React.js uses a "virtual DOM" made up of JavaScript objects, so there isn't any concatenation of HTML strings, just generation of virtual DOM objects. The next step up from that is their JavaScript variant, JSX, which has HTML-like syntax for instantiating those virtual DOM objects.

JSX looks quite like HTML templates, except the programming logic (which in a templating language might be {{if foo}} ... {{/if}} etc) is plain JavaScript. Introduction to JSX here: http://facebook.github.io/react/docs/jsx-in-depth.html

Slide 49 has a bigger example, and the slide before shows the plain JavaScript version: http://murilopereira.com/the-case-for-reactjs-and-clojurescr...

When I was first looking into Single Page App frameworks, I came across the usual Angular/Ember.js recommendations and tried to get started with them multiple times. I couldn't get myself to stick with them and always went back to mostly server-side rendering with jQuery / Ajax / Pjax tech until I tried React.js later.

The primary reason for my dislike in using the Angular/Ember type frameworks is that they have their extensive custom template code and directives that to me was basically like learning a whole new language -- I had no desire to learn things like the framework's method of doing a foreach loop in their own custom way when I can just use JS' foreach with React. I was also not a fan of throwing in all the non-standard tags into my HTML. With React I can write the view in JS or, my preferred method, JSX which is basically plain HTML with curly brackets for variables that compiles into pure JS.

I agree. While I'm not as familiar with Ember, one of the things that has kept me from using Angular on more than a few complex pages, is that I would have to rewrite all of the otherwise-functional Handlebars templates we have made thus far. I've even done six or seven custom directives now, and have a feel for "the power of directives" (having heard that phrase a lot), but it certainly isn't what I use most of the time.

But this is all an aside from the point of "templates" in general.

When I think "templates" I tend to think first of something lightweight like Mustache or Handlebars templates, that I can render client-side (and server-side!) without worrying about anything beyond decorating HTML with a few curly-braces.

> While I'm not as familiar with Ember

Ember currently uses Handlebars by default, and will be switching to HTMLbars[1] soon, so it's even better.

1: https://github.com/tildeio/htmlbars

Sounds similar to the "no schema" claims by the NoSQL crowd. I see good reason to have a defined schema in most cases.

There are better templates approaches that don't use string concatenation like HTMLBars and Meteor's Blaze.

Decent presentation.

Something that would be really helpful for me, as a consumer of these slides, would be to have a better setup between the slides with just code. I get the impression that, with some of those slides, you would be saying something while that slide was up. But without your audio, I have no idea what that is and so the slides are confusing at that point.

So, if you are giving a presentation that goes best with audio, it'd be awesome to have the audio. If you are giving a presentation with the goal that it can be consumed without the audio, would it be possible to have your speaker notes show up on the slides where you are showing something and talking?

All that said... I'm very interested in looking at react.js. I don't know that it would work with the team that I am working with now, mostly because the team that does the front-end work doesn't do JS programming so much as they format HTML and CSS.

Does anyone know of something that mixes react.js with templates? Any success/failures in that regard?

I am the lead guy of a React library: https://github.com/wingspan/wingspan-forms

All the design work was done by an actual designer who maintained the JSX directly. He knows enough javascript to get around but basically he just pretended it was HTML. JSX is awesome because it means designers can commit directly without involving engineering.

As a developer I'm interested enough to try React.js on my next project. However, it seems like designers will still need to write Javascript to implement repeating structures (tables, lists, etc.)? Just like designers don't want me fiddling with their HTML and CSS, I don't want them fiddling with my code -- but React.js's model seems to make such a separation of concerns impossible?

You can of course continue to have designers handoff markup/CSS for integration by engineering. But if your designer can handle basic javascript, you needn't involve engineering at all. In practice it doesn't really matter if the individual views are sloppy javascript since React separates concerns so well.

How does JSX fare by the "don't trade simplicity for familiarity" standard?

It's just an alternate syntax, so i consider them equivalently simple

React comes with it's own 'template' library called JSX. It allows you to mix React/JS and html.

Example: function render() { return <div>Test</div> }

You don't need to "mix" React with templates because JSX files are very similar to HTML, except for a few gotchas[1].

We have JSX components that look like templates and have little logic, so they are as straightforward to our designer (who only knew HTML) as possible. He tweaks them all the time. For example, it might be a component like `Button`, `FormField` or `UserItem`.

We compose those simple elements into more complex JSX files that have more state and logic, like `FeedbackForm`, `UserProfile`, etc. Still, designer can work on them, if he wants to change DOM layout or CSS classes.

[1]: http://facebook.github.io/react/docs/jsx-gotchas.html

Yup, in my experience getting designers to work on the JSX has been a far smaller headache than I initially expected.

At least for ClojureScript there is https://github.com/ckirkendall/kioo which is based on https://github.com/cgrand/enlive

I not sure there is a similar thing for plain React/JS though.

This. Enlive and now Kioo are elegant solutions to the problem of letting designers and programmers work independently. It still amazes me that something like Enlive hasn't popped up in other languages/frameworks.

I have often wondered the same thing. I created enfocus and kioo to solve the exact problem you stated. How do you get designers and programmers work efficiently together? This is particularly difficult with single page applications.

I think I get it. Can anyone let me know if this description of my understanding is close to correct?

React lets us program reactively by rerunning the entire JavaScript description of a component every time its data changes. This lets us use "normal" JavaScript code to describe our component (as opposed to explicitly attaching Ember dependencies or using Angular ng-* attributes). This normal JavaScript code will describe the component at all points in time, not because there is two-way binding, but because any change in the state of the component will cause the entire JavaScript function to re-execute.

React's virtual DOM, then, doesn't have anything to do with reactive programming per se. It's just the way that rerunning JavaScript code for every single data change can be made performant.

Have you ever programmed graphics?

To make a paralell, usually in graphics your main loop reacts to events (user input) and you change some internal state in some object(s). Finally, you get all those objects that know how to render themselves, see what's relevant and render the whole scene. You don't have to care about pixels, you just react to events and blit a representation of the entire state.

React.js is the same, the difference being your components "render" themselves to the DOM, and because it's a tree, it's naturally composable. It's still a pipeline taking state and outputing a representation though.

That is retained rendering with scene graphs. Immediate-mode rendering is obviously very different.

Pretty much. It's similar in spirit to reactive programming if you think of a component as exposing a Signal<Virtual DOM> that the renderer subscribes to. Also, the Signal<Virtual DOM> depends on a Signal<Props> and a Signal<State>. And the Signal<Props>, in turn, depends on the component owner's Signal<Virtual DOM>.

You also have control over whether the render() method is called by substituting your own diff function (shouldComponentUpdate).

This sounds correct.

The simple v. easy section was interesting. Those words are probably used too often as synonyms. In reality, we should think of them differently - something easy is something that a lot of people should be able to replicate without much expertise, whereas something simple, a lot of people should be able to understand (what it does, the purpose, how to use what was built), but not necessarily replicate themselves. I think that is probably the right distinction, although it is a very fine one.

If you haven't seen it before, check out Rich Hickey's talk on the topic: http://www.infoq.com/presentations/Simple-Made-Easy

Thanks! Never had seen it, really interesting.

You're off for a retreat if this is the first time you are seeing this talk!

And in case you missed any of the others, this is a great list:


> Immutable data structures make React's diffing algorithm really smart.

I was very intrigued when I heard this claimed in a blog article a while back. So I investigated this claim deeply and was not entirely convinced. For example, the immutable approach to tree diffing actually requires more work in some cases, since you always have to diff from the root.

I wrote more about this here: http://blog.reverberate.org/2014/02/on-future-of-javascript-...

This actually isn't true anymore that you always have to render from the root in Om. We've already changed component local state to avoid this, and likely in the near future this will be true in the props case as well.

Thanks for the update -- could you explain how this works? Do you figure out internally-to-Om which subtrees have actually changed and call setState() and/or forceUpdate() on them?

The original article said that Om doesn't use setState() at all -- has this changed?

"Om is an immutable data structure library"

The immutable data structures come from clojurescript, all the default data structures in clojure/clojurescript are immutable.

Om is react.js bindings for clojurescript and some state management functionality.

You can't blame me for disregarding everything after that mistake can you? It casts quite a bit of doubt on "I investigated this claim deeply".

If you see any factual inaccuracies in the substance of my conclusions, please let me know (for example, swannodette's updated information in a sibling comment is very useful). I will update my article to correct the distinction you mentioned.

> You can't blame me for disregarding everything after that mistake can you?

Yes, I think it's unreasonable and uncharitable. Any nontrivial piece of work is going to have mistakes. I was investigating a set of technologies that were totally new to me (React, ClojureScript, Om) and I had no friends who were experts in the subject matter to review the article for me prior to publishing it. Given that, I think I did a pretty good job actually. The mistake you mention has no impact on the article's conclusions.

My article was not attacking or argumentative, but a good-faith attempt to understand the prior article's claims better.

I also didn't mean that as an attack, disregard was probably the wrong word to use.

I meant that since it is indeed a non-trivial piece of work and the performance characteristics in question are very complex and depend quite strongly on the Clojure state model then it's reasonable to assume your conclusions are wrong because of the mistake made at the start of your chain of reasoning.

For example: "And it is hard to imagine convenient two-way data binding being built on top of immutable data structures." makes perfect sense if you are working in javascript, but is a normal and elegant way of doing things in clojurescript (and the cursor implementation in Om makes them incredibly convenient).

I'd rather use a typed language which is why I'm following the development of PureScript ReactJS bindings.



David Nolen (@swannodette) has been doing some great work in Om with ClojureScript and React. In addition to the links posted - this is a link on why ClojureScript's data structures (functional with structual sharing) make implementing undo trival in Om http://swannodette.github.io/2013/12/31/time-travel/ and this is a link on data binding in Om with :instrument http://swannodette.github.io/2014/02/27/taking-off-the-blind...

Um, a lot of what I see in React.js reminds me of Knockout.js but without the data binding on the view side. I know there's a lot more to it than that, but the simple example seems like something Knockout's MVVM model could handle in similar or less complexity.

So why use React.js when Knockout.js works perfectly fine?

Maybe it's easier to see by example. Knockout doesn't do so well when the state isn't trivial. Build these in Knockout, I dare you to try. (Once upon a time, I tried, and failed, and now I use React)

http://wingspan.github.io/wingspan-forms/examples/form-twins... http://wingspan.github.io/wingspan-forms/examples/faceted-se...

These seem to be React wrappers around KendoUI. There are wrappers in Knockout for the same library as well. http://kendo-labs.github.io/knockout-kendo/index.html Writing custom bindings in Knockout is quite easy. I also do not understand the appeal of React. Performance is often cited because of the virtual DOM implementation, but for example in this benchmark Knockout is three times faster than React in my browser. http://vuejs.org/perf/todomvc-benchmark/ The only criticism that can be made against Knockout is the syntax when using observables in bindings (the ugly and error prone parentheses) and lack of reusable components. The first is solvable by using the Knockout-ES5 plugin if we are willing to drop IE6 to IE8 support. As for the second, components are finally comming to Knockout: https://github.com/knockout/knockout/pull/1396

For the record (for anyone who is following the discussion), I have used the KendoUI/Knockout bindings and am comparing Knockout and React on equal ground. Nothing about the programming model would change if you just used straight HTML <input>s.

The main issue with Knockout here, is that the state of these apps (the JSON blob that changes as you click around) is not nice and rectangular and doesn't fit nicely into ko.observable and ko.observableArray. particularly the faceted search demo has tension where the lefthand facet checkboxes are grouped and have counts, but the top facet list is not grouped and don't have counts. In react, those are backed by the same state data, and the data is just regular nested javascript objects and arrays, you don't need to access the data through observables. You just use underscore to transform the data as you see fit.

Uh, both seem relatively trivial. I've built considerably more advanced stuff in Knockout.

This seems slightly cribbed from "Rethinking Best Practices" by Pete Hunt https://www.youtube.com/watch?v=x7cQ3mrcKaY

Pete Hunt is quoted on one of the slides, so that sounds likely :)

function renderApplication(tweets) { return(document.dom.ul( { class: 'tweets' }, tweets .sort(compareTweetsByScore) .slice(0, 5) .map(function(tweet) { return(document.dom.li({ class: 'tweet' }, tweet.text); }) )); }

What I like best about Ember and Angular.js is that you don't have any hint of the DOM in your controllers. I don't like how the above example mixes concerns.

Its concern is mapping the tweets (data) into a view (another form of data). That is one concern. If you like, you can split it into smaller functions (since everything is referentially transparent, unlike in MVC), but that would be overkill considering the given example.

the point i think is scope injection makes controllers clueless about any view responsability. That's a powerfull idea. Well they are not totally clueless because one still needs to "force update the view" sometimes in Angular ($scope.$apply),but this can be avoided by using Angular promise api.

Pete Hunt talks about this in Rethinking Best Practices video[1]. This is one concern, not two.

[1]: http://www.youtube.com/watch?feature=player_embedded&v=x7cQ3...

This would be considered part of the view, not the controller, and would thus be organized as such. It's also a very small example - a real application would have a number of differences with this.

Anyone knows more about "doing the rendering in web workers" part?

Is it really possible?

Someone doing it already?

Any real benefits of that (web workers have their own overhead)?

It would be useful to see side by side benchmarking and comparisons of typical Javascript vs React.js. I've just finished reading High Performance Browser Networking, and it appears to me that most client side code is slowed down much more by the network than the language. Am I missing something here? Is Javascript really that bad on its own?

In my experience, JavaScript is quite fast in most browsers. Communication between the DOM and JavaScript is much slower and causing lots of layout invalidation and repaints absolutely kills an app's perceived performance. React's approach is simple for the programmer but takes advantage of the fact that JS is fast and minimizes those slow bits.

I like the idea of React.js and immutable data. But i'm not a fan of the lisp syntax, am i missing something?

I used to have an issue with lisp syntax until someone pointed it out to me like this.

In c and java like languages, you invoke a function like this: f(x)

In lisp, just move the paren before the function name. What's the big deal? (f x)

Similarly, f(g(x)) becomes (f (g x)). All we did was move the paren before the function name.

The syntax is extremely consistent and it makes the lisp syntax trivial to learn. In nearly everything you do, the function name comes first the arguments come next. (+ 1 2) Here + is a function, and you are giving it 2 arguments. There are no special operators or syntax to learn. Just functions!

The mind blowing part comes when you realize that this consistent syntax combined with the fact that the code is really just written in lisp datastructures, is what makes lisp macros so powerful.

Interesting, that does provide a highly consistent base as you say. I might just have to try out Closure with Om/React for my next project.

Is the presentation available anywhere? The slides just don't cut it for some of this.

Why isnt clojurescript compiler written in clojurescript? i cant run java on my machine.

You can read more about the ClojureScript compiler here: http://swannodette.github.io/2014/01/14/clojurescript-analys...

If it's written in Clojure, couldn't you just self-compile that Clojure into JavaScript? I suppose you might have to make a few changes, but it doesn't seem like it would be that difficult to port... Speaking from ignorance here though.

Out of curiosity, why not?

Okay, I'm sold!

Just the slides aren't enough to sell me here, I'm sure the missing video to go with this fills in the holes.

Buuut. "Problem - UI is complex - because DOM not Reactive - what if it was reactive - random code sample", is just non-sequitur out of context.

DOM programming is inherently "reactive" - it's event based.

Furthermore, I think it's nice that tools like React.JS exist that "free the developer from manually programming the DOM", but that's exactly what Angular.JS offered too. Automatic binding and updating yada yada. Why is this author flaming Angular.JS? Was it because its leaky abstraction turned out ugly over time? Well the same fate is awaiting React.JS and its "minimally leaky abstraction".

Leaky abstractions never remain "minimally leaky" over time. The fact they're leaky from the very start shows the model was flawed to begin with.

Angular.JS does manual compare between two large model objects to detect changes and emit model update events.

React.JS does manual compare between virtual DOM and real DOM and emits DOM update events.

They both try to solve the hardship of having to update your DOM, via an abstraction that only works well in specific circumstances and incurs irreducible runtime overhead when behind the scenes structures have to be compared over and over and emit update/change events.

Sometimes the problem is in the platform. But even more often a bad developer blames the platform for their own inability to architect their app cleanly and thinks leaky abstractions are the answer.

The reason UI programming isn't reactive is because reactive systems are immediate mode (describe the whole state at any point in time) and the Dom (hell, most UI toolkits) is retained mode (stateful). So you need to abstract that away somehow and that abstraction is guaranteed to be leaky to some degree.

The thing that separates react from the rest (disclaimer: I work on react) is that these leaks are pushed to the edge of your system (that is, you need an external signal to re render) rather than threaded throughout your system (like requiring everything to go through $scope for one). We have seen massive dev efficiency gains because this removes many limitations for not much downside.

Hello, Peter.

Incidentally I was just watching one of your presentations on YouTube to understand the reasons behind React's design choices.

The thing I still can't understand is why we need to model the UI around emulation of immediate mode.

Two big reasons:

1. The fact is when you want to create a meaningful animation between one state and another, you need to be aware and in control (as a developer) of what exactly the change is. Diffing may produce one possible valid state change delta for the developer to work with, but no guarantee it'll be the correct one. So what does that mean for animated transitions? Is immediate mode dooming them to either not be used, or to be semi-arbitrary depending on what the diff engine decides?

2. Fact is that the browser usually has no access to the full server-backed state of the widget that it's rendering. Instead, the communication with the backend that powers said widget (say a chat box) is in the form of delta state changes. You don't get the full chat log from the server every time someone sends you a chat message, you get the change only: new message from x.

So if we need to be "state aware" and communicate with "state change events" so to speak with the server anyway, why suddenly drop that knowledge and pretend all the state is local by emulating immediate mode rendering?

It doesn't feel like less work. It feels like more work, and less possibilities (said animations in point 1).

Thumbing this from my phone so can't go into as much depth as normal.

1. The diff algorithm is deterministic and accepts that some widgets are stateful. You can tell the system which items to preserve and which ones to destroy by providing an identifier. This is essential complexity in the current world we live in (global dom state tied to element instances like focus). If we were to throw out the Dom spec and rebuild it we would not need to do so much.

So you can animate by tweeting a value and rerendering/diffing every frame. Facebook look back video editor works this way.

2. Yes, but delta updates are imperative mutations over time and humans are really bad at keeping track of them so we should try to isolate them as much as possible. We have a separate system that coalesces these deltas into consistent views of the world which are then passed to react. This is also the role of systems like rx.

One way to think about it is like rest. People like rest because it is predictable: URL refers to the same resource always and refreshing the page always works consistently and you never need to think about deltas.

I tend to model and see all communication (at all levels) as message passing and not as resource/state snapshot passing, but the web has worked fine with the latter concept so far. So React's architecture certainly provides value in such situations.

Thanks for answering my questions.

Totally get you on that. I think that message passing is valuable because it forces you to decouple systems in a way that reduces shared state. But for complex apps this means that you will probably have to introduce some sort of coordination system, which is where things start to get complicated. If you can pull "time" out of the equation (ie look at complete state snapshots rather than messages over time) it can make things a lot easier. Obviously not appropriate for everything, but has worked well for us when building UIs.

No problem btw, fire away if you have any more questions!

One approach to the animation issue is to use CSS transitions. This way your code is just responsible for setting the new value (which can be done by Om/React or any other approach) and then the browser is responsible for making the animation happen appropriately (and efficiently, with full hardware acceleration, etc).

This is, for example, the approach suggested by Kevin Lynagh for use with his awesome C2 library which is like D3.js for ClojureScript and which comes with no built in animation support whatsoever:


I'm not a front end developer and so I don't spend too much time on this type of stuff, but when I have had occasion to use it, I found this approach much more pleasant than oldschool jquery style approaches to animation.

Check out this talk: http://vimeo.com/92687646

At around 30:00, he talks about why Angular's two-way binding is evil, and why React's approach makes more sense. In short, two-way binding means there is no single “source of truth”. That makes debugging and non-trivial interaction very difficult. React solves this problem by always having one source of truth—component's `props` and `state`.

Thanks, bookmarked.

> Buuut. "Problem - UI is complex - because DOM not Reactive - what if it was reactive - random code sample", is just non-sequitur out of context.

How is it a non-sequitur? Random Code sample? Are you being a little too aggressive maybe.

> DOM programming is inherently "reactive" - it's event based.

I don't think you quite know what reactive means.


Maybe you should look a few things up before jumping in.

> Why is this author flaming Angular.JS?

If you are a proponent of it and you think you are defending it here, you might actually be doing it a bit of disservice.

He made the point that Angular JS is complex and showed a list of new concepts it introduces -- services, directives, etc on top of the already existing ones, controllers and so on. It is a personal opinion. You don't think it is complex, ok, share your opinion, it doesn't mean the author if "flaming" anything.

> They both try to solve the hardship of having to update your DOM, via an abstraction that only works well in specific circumstances

They both solve a similar problem with some differences. Author thinks one does a better job sometimes.

> . But even more often a bad developer blames the platform for their own inability to architect their app cleanly and thinks leaky abstractions are the answer.

Are you implying the author is a bad developer? Can you show that. So far you haven't

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact