I'm a big fan of React. I soured on Ember but, to be fair, haven't looked at it in quite a while. Curious, though, is the statement in the slide deck that Ember "dominates" big apps true or verifiable? Perhaps if you exclude toolkits/libraries like Backbone, and compare only to Angular, I could buy it.
Ember isn't smashing anything. Besides the obvious Google, Angular is used by Udacity, Nike, Virgin America, HBO's mobile app, MSNBC, Salesforce, Amazon AWS, Sony's PS3 Youtube app, and General Motor's in-car interface. Sounds like plenty of big apps to me.
Interesting. Thanks for the list. My biggest issue with Ember, other than the management of release schedule and API early on, is the concept of tying routes to models explicitly. It seems to assume that given a route context, you'll be dealing with a particular model - and only one particular model. If you want to have an additional data context, you need to establish route and then tie the routes together within one template.
This seems to confuse the relationship between a URL and the data displayed on the page.
I've really enjoyed React+Backbone, on the other hand. Very small footprint and gives me flexibility to design and build an application. After spending years with Rails, I've come around to "convention over configuration" is a nice thought, but breaks down at certain sizes. And it seems to break down much more quickly on the client side.
To me, personally, well-written Backbone+Underscore+React runs circles around the newer JavaScript frameworks. It's not to say the debate is over and settled - I just haven't found the complexity and size of frameworks like Ember to pay back more than they cost.
Ember has now got one of the best (IMO) release cycles in the business. We borrow heavily from Chrome, and have a very polished release infrastructure, with release, beta and canary channels you can subscribe to. Additionally, we have a strict commitment to SemVer and most Ember apps are on the latest release.
As for the complaint about tying models to routes: Ember does want you to have a model per route, but the model can be any data structure you want: an array, a hash with multiple models, or a single model.
I'm not sure exactly what issue you hit, but most apps of any complexity have multiple models on the page, and of course that's something we support out of the box. (You can see this if you open any production Ember app in the Ember Inspector browser extension, such as http://vine.co or http://twitch.tv.)
I feel like these somewhat restricting patterns can increase your productivity massively. If your app fits the restriction. If not, it will slow you down.
There is usually not enough emphasis on the nature of the app in these X vs Y framework discussions.
I can really see why you would choose Ember say for Discourse and why (once you got it) it is very productive.
But for other apps you might constantly fight the Framework.
Optimal patterns really depend on what you want/need to do. (Thats why TodoMVC doesn't help much).
Yup, we've just started recently. Too soon to give any value judgements on it but this article https://news.ycombinator.com/item?id=8248536 made a lot of sense to me and I'm cautiously optimistic about Flux overall.
For pages with a great deal of local/global state, we've taken a page from David Nolen's Om library and have a cursors library written for react using react's immutability helpers.
IMO, pairing global page pub/sub with heavy local modification doesn't seem like a good pattern for effective state management. It seems less problematic at scale than two-way databinding but problematic nonetheless.
Can you provide proof that Angular is not being used to build similar big apps? The quick research I've done shows the opposite, and that Angular adoption is quite a bit higher than Ember.
Mostly small projects and stuff. Angular definitely has a larger community, but from what I can gather on the internet Ember is used much more often as the entire basis for large applications.
Regarding https://builtwith.angularjs.org/, It kills me how a page so important to the marketing of Angular is so poorly put together. The pagination wraps over the footer and if I go to another page and refresh, it starts over. I'm not an Angular hater by any means, but I would think that it might be important to at least have a clean experience when trying to market the framework.
Every time there is any post on Ember, it starts a flame war. As @tomdale would say it, it was ember vs backbone, then ember vs angular and now ember vs react. In today's age of minimalism and extreme flexibility, Ember is very complex and huge - but that is actually it's strength. Build a massive app with just 2 people on the team and you will know why ember users swear by it.
I really enjoy React's concepts. I have but one nit to pick with it and it's meta: mixing grammars in a single buffer really hoses syntax highlighting & indentation in emacs.
I'd much prefer to be able to "require" the JSX where I need it and have the right context passed to it. That way all the editor-specific nonsense can just be avoided.
You could look into Mithril (a smaller React-like framework). It mixes JS and CSS syntax to achieve terseness, and it does so within the rules of valid javascript:
The problem with this is that whatever you require() won't close over other variables/imports unless your preprocessor is straight up compiling JSX into JS and inserting into another JS file, which is kinda gross and eval-y.
As @dugmartin mentioned, it's really quite nice if you are using coffeescript. It ends up resembling templating in a lisp, something akin to hiccup for example.
I imagine a similar effect can be had with ES6 destructuring assignment, just with more commas and mandatory array brackets.
I realized some time ago that the run loop inside Ember (aka Backburner) is really similar to Flux.
In Flux, everything is powered by the dispatcher. Changes to the store goes through dispatcher. All the stores changes that react to another store change needs to settle before re-rendering. This is almost exactly how to run loop works. The run loop is the dispatcher.
So in theory, we can just use Backburner to power a Flux app.
React does a similar batching of updates to avoid unnecessary rerenders, but a critical piece of the Flux dispatcher is helping organize inter-store dependencies which (unless I'm missing something) neither Backburner nor React itself does:
I'm just starting with React, but IMO referring to the models in the component and calling methods on them is like the equivalent of calling actions through the dispatcher?
1. Stores can contain more than one "model", they cover a certain "domain"
2. Stores contain immutable data. This allows for reference equality checking which will yield performance gains
3. Stores do not contain asynchronous code. From the view of stores, it doesn't matter if user manipulates the state directly or triggered a fetch from a server.
Using Backbone models is a valid strategy in my opinion though...
Thanks for slides. In this slide http://goo.gl/XDk0J0 you mentioned you would talk about alternatives to passing down callbacks later? Did I miss that in the deck or was that just spoken to?
There are heuristics to prevent recursing into obviously-removed/added elements (using component type and keys), but aside from that, there's always going to be a tradeoff between frameworks/libs that choose to track this granular information to know exactly where a change originated and what needs to be updated, vs libraries like React that don't set up any sort of observers or have any sort of knowledge about where the change originated from, and React has demonstrated that their approach is pretty fast due to the fact that live mutable DOM manipulation is the bottleneck and not purely JavaScript traversals.
Awesome slides, even having very little experience with EmberJS and React it explained very well what Reach does and is, and why I would want to use it, better than most tutorials out there (at least the ones I have come across).
"If you're going to hate on React for some reason, make it something other than JSX"
But what if I hate JSX? It's such a tight coupling to the DOM which is just the opposite direction I want to go where the DOM doesn't even matter. But that's just my opinion I haven't done enough research or investigation to try and prove one over the other.
I slightly disagree with @machty. I agree that most of the reasons people give for hating on JSX are somewhat off the mark.
HOWEVER: the fact that JSX is XML and not HTML syntax is a real issue. `<label for="foo">` doesn't work; you have to know that it's `<label htmlFor="foo">`. Same with `class` and `className` and multi-word (`maxwidth` vs. `maxWidth`).
Early on, before React had fully made the decision to stick with raw property names, they understood the value of making JSX "just HTML" (see @petehunt at https://github.com/facebook/react/pull/269#issuecomment-2291..., for example). The decision that they made is totally reasonable, but having to learn an XML dialect of HTML (not XHTML, but a dialect that uses property names for attributes, and disallows normal attribute usage) is not free.
That said, I'm sure it's something you get used to quickly, and isn't something that slows you down much once you understand it.
It's not even XML — it's JavaScript. The problems with for/class/etc. problems aren't because of XML, but exist because the preprocessor just translates everything to React.DOM element declarations, and of course "class" et al are reserved words in JS.
I agree that's it super awkward. I have no idea why they don't let the preprocessor be HTML-aware and translates class into className directly. I can't see how something like "class" would clash with the surrounding JS syntax given that it's specific to the local tag syntax. <Foo> isn't valid JS, after all, so why should "class" not be valid JSX?
It creates a maintenance problem, too, because React has to play catch up with every HTML tag and attribute and every CSS property.
Because it's such a thin layer over JavaScript, you don't have to port/reimplment all the stuff that JavaScript has already solved to your templating language / abstraction of choice. I still prefer Handlebars, but JSX elegantly sidesteps lots of issues at the expense of not actually being real HTML and handling flow control stuff somewhat awkwardly, but you really gotta try it out to get a feel for the tradeoffs.
Then you didn't understand what JSX is. JSX is just optional syntactical sugar for declaring (virtual) DOM elements. You can use all of React with JSX and your code will be only slightly more verbose.
Your objection is to the very tight coupling of the DOM to React's component abstraction. That's a very valid objection, but unrelated to JSX.
Given the extremely tight coupling between the template and it's context (a controller/component), the concerns are the same, and splitting the DOM into a template is an arbitrary separation of technologies rather than a legit separation of concerns
I get that but disagree with it. I don't see it as an arbitrary separation but a necessary one based on separating the view (which a team of designers can freely modify without worrying about breaking anything or even touching the logic) from any logic that can handle events.
Honestly I try to use messaging where possible for these types of things. The last app I wrote should, theoretically, be able to be moved from an HTML app to a node-qt app only by swapping the views.
But like I said I haven't had a ton of experience with either so I can't make any good, factual points here only my personal preferences and anecdotes.
> separating the view (which a team of designers can freely modify without worrying about breaking anything or even touching the logic) from any logic that can handle events
Where does the designer's job stop ? Does he not handle animation ? Should he be in charge of CSS too, because that's how you do basic animations ? Why shouldn't he be in charge of slightly heavier animations, just because they're in javascript ?
The point of the authors (which I agree with) is that the whole notion of "view == template" is wrong, and thus "view == html+css files" is wrong. A view is the thing the user interacts with: a button, a list of items, a search bar. All these components should be handled as a whole, and should be handled independently from one another. If a component doesn't need any javascript for it's logic, fine; if another component needs some javascript for whatever reason it's nonsensical to separate this javascript. A design doesn't always stop purely at static appearance.
The fundamental unit is the object you're working on, not the technology you're using.
If the rule is a) designers only touch .html/.hbs files and b) only developers touch the view/controller .js files, then if either of them change a property name from `{{displayName}}` to `{{display_name}}`, the whole thing breaks, which is the coupling React is trying to avoid by keeping these similar concerns within the same technology/file (JavaScript).
"(which a team of designers can freely modify without worrying about breaking anything or even touching the logic)"
wut
edit: JSX accomplishes this goal handily, no other tech i have ever used comes anywhere close to JSX, and I have used nearly all of them. (I'm the engineer who manages the designer and integrates his changes. Interactions with the designer are like, "Go to line 37 of XJZ.js and make it look like foo." In JSX, there usually isn't any integration to do as he can commit directly. Which is why JSX rocks.)
Never worked with web designers? Typically folks who are great with design and doing some styling and markup? We have some really awesome folks with the current company I'm with so they frequently work with the developers to make their shit sexy.
Edit: to address your edit that seems overly complicated to me. Most of the web designers (or designers in general) don't know a lot of JavaScript; asking them to make structural changes inside of JavaScript worries me a little. I'd much rather them change the view in its natural state: html and css. JSX isn't that.
Every thread on React has your comment- JSX sucks or it looks like PHP (which sucks). Half of the thread is then devoted to refuting the comment. At the end everyone's opinion has calcified.
I would highly encourage you to try it before you dismiss it.
JSX is optional, but I've come to really enjoy it.
Here's why:
1. Right next to the logic of how a component is meant to function is the markup it will ultimately render with (or something pretty close to it).
2. I still avoid, for the most part, "magic attributes" like in Ember and especially Angular.
It's not perfect, but it is optional. If you're fine transforming CoffeeScript (a bad example - I can't stand CoffeeScript:) then find an inner peace seeing some XML in your JS documents.
On the subject of CoffeeScript and React/JSX, our team uses something like this[1] to reduce the need for `React.DOM[...]` or lots of `requires` to components.
Our components end up looking like this. As a CoffeeScript/Jade fan, I obviously like it:
ReactElementBuilder = require './lib/react-element-builder'
# Example: add react-bootstrap components.
ReactElementBuilder.addMany require('react-bootstrap')
MyComponent = React.createClass
mixins: [ReactElementBuilder.mixin]
render: ->
@e 'div#main', null,
@e 'Navbar.fixed',
onClick: @handleNavbarClick
'Hello my name is Navbar'
"It's such a tight coupling to the DOM which is just the opposite direction I want to go"
That's what I liked about ExtJS4.
They had their own "virtual" component model, which then was rendered as DOM later. But the DOM could change in different versions, because of performance reasons.
There was/is probably much wrong with ExtJS, but I liked this approach.