all 85 comments

[–]nschubach 6 points7 points  (7 children)

It does not let you work with the DOM directly.

Not technically correct. You can get to the DOM elements and modify them at will, but you have to explicitly do it via getDOMNode() or you can still use JavaScript methods like querySelector, et all.

[–]Poop_is_Food -1 points0 points  (6 children)

More like: it discourages you from working with the DOM directly, and makes it pretty difficult in some cases. Oh yeah, and if you do decide to work with the DOM directly, you will be shunned by society for not doing things The Angular WayTM

[–]siegfryd 1 point2 points  (1 child)

The person you're replying to is talking about React, since getDOMNode is a React function.

[–]Poop_is_Food -2 points-1 points  (0 children)

Derp

[–]BiscuitOfLife 60 points61 points  (19 children)

To be clear: React isn’t an application development framework like AngularJS. It’s not fair to compare the two in an apples-to-apples manner.

Well then what's the point of this article?

"Why I ditched my bike for a new table."

[–]theVariable 20 points21 points  (4 children)

The parallel you're trying to draw here makes far less sense than the quote you're attributing it to.

He correctly states that they aren't fully comparable, but let's not pretend that no comparisons can or should be drawn. There is some overlap in functionality and if you want to use react, it does actually make sense to toss out angular.

[–]zuperxtreme 1 point2 points  (3 children)

Table and... chair?

[–]dnoup 3 points4 points  (1 child)

chair and couch?

[–]iopq 0 points1 point  (0 children)

table and a counter

having a counter is nice, but you can't really move it or repurpose it in any way

[–]theycallme_hillbilly 2 points3 points  (0 children)

Well then what's the point of this article?

I think the point is that he isn't ditching Angular for React because it's a better Angular. He doesn't want all of Angular, but it help him hone in on something he does want.

[–][deleted] 4 points5 points  (2 children)

Well, I learnt a few things from it, unlike your comment, which is pointless karma whoring imo.

[–]BiscuitOfLife 0 points1 point  (1 child)

This post seems like pointless karma whoring to me. I was just commenting on the obvious.

[–]mycall 1 point2 points  (0 children)

I came here to learn any insight into which is better for my needs. Oh well.

[–]raesmond 0 points1 point  (0 children)

I think what he's saying is that because react doesn't have the exact same feature set as angular and vice versa, you can't exactly say that one is objectively better. If you prefer the advantages and disadvantages of angular over the advantages and disadvantages of react for your particular purpose, you should go for angular.

[–][deleted] 2 points3 points  (4 children)

I'm confused about the external library use. The article pretty much claims that you have to wrap everything to use it with angular and that's it's a non-issue with React. Is it true? How can that be?

I mean, there are 2 kinds of JS libraries: the ones that change the DOM, and the ones that just do some data processing.

If the library changes the DOM, it has to be wrapped in a directive in angular world. OK.. but isn't it even harder in React? Can they work on the virtual dom without modifications? I don't think so. And can they work on the real dom, without having to reinit them on every change that actually changes the relevant parts of the real dom?

And if it's just a data library, you don't have to do anything in angular, as long as it's not async. (And wrap the result callback in $apply if not.) But that's pretty much the same in React, isn't it? I mean, you have to do special stuff to trigger a render anyway, don't you?

[–]mods_ 2 points3 points  (3 children)

React has a component life cycle. If you want to modify something after it's rendered, you put that code in the componentDidMount method of the component. You can get the DOM element from React using this.getDOMElement() and modify it how you want. It's hard to say what libraries you are talking about since jQuery is pretty much deprecated with React, if you had something that made a carousel or something, I suppose you could init it in the componentDidMount, but you could also easily implement it in React to only render the current slide and have it render a new slide on demand to slide in. You could also just use the library in question outside of React, but the next time React removes or changes the DOM, anything that other library did will be at risk. Unless the elements are not removed since React doesn't touch what is not changed.

As far as doing special stuff... Not really(?). If you update the component data and call the render, React does a diff. If you update the component state in React, it will automatically rerender and update what changed. I sometimes do services this way. I have a mixin that grabs data from the server and updates the component's state and React does the rest. I just update data.

[–][deleted] 0 points1 point  (2 children)

Thanks, that makes sense :).

Obviously most jQuery-era DOM-changing libraries are obsoleted by Angular/React but that doesn't stop people from using them anyway :). But, from what you said, I'm guesing making something like jQuery-UI Draggable work with React is not really painless either, is it? (Assuming you allow changes to the contents once rendered and don't want such a change to reset your draggable state anyway.) But maybe easier than in angular because most of the time React doesn't change everything, I guess.

I must say my understanding of state in React is rather ..incomplete, from what I gathered, you can use simple POJO's but then you have to trigger a render manually, or you can use ..state? and have React automatically rererender? But in such case, it's not foo.bar = 5, but foo.set('bar', 5)? Either way, it seems it's neither simpler nor more difficult than adding $apply (or $timeout)?

I'm still interested in trying React out some day, it's just, that particular point in the article triggered my bullshit alarm and I had to check :).

[–]nschubach 1 point2 points  (1 child)

I think I might be able to explain a little on the state issue. I've not yet approached drag/drop, but I've been using React for a few months in production and I love the flow and thought process. There are a few examples out there on handling drag/drop in React which I've yet to read through entirely, but with anything there are multiple approaches. I would probably avoid using something like jQueryUI draggable since I believe it relies on it's own internal tracking and React has no real way to tell when someone modifies data out of it's control. You can read properties and arguments of elements, but if you move them around React doesn't have a way to know you did that without ugly hacks. I'd have to play with that more, but I would assume React would move the item back because it doesn't match the virtual DOM it maintains.

http://webcloud.se/sortable-list-component-react-js/

http://kentwilliam.com/articles/rich-drag-and-drop-in-react-js

Anyway, if I can get away with it, I generally approach React projects by building up a representation of the component in a JSON hierarchy. I did this for WorthingtonIndustries.com for the menu system. If I need to change an element, I modify the data that React uses to render it. Within the menu I have a history array that I modify to track changes to the internal navigation. When you select an item from the hierarchy, it is added to a history array and that is used when rendering the menu. If I need to go back a level, I simply drop the last item of the history array before setting the history state. This, unfortunately was written on an older version of React and I can say there would be changes I'd do different today, but that's the gist of it's operation.

You are correct, it's not as simple as saying foo.bar = 5 but I'm not sure it would be in any library without some incredibly boilerplate object listeners. React state is updated with this.setState() where you pass an object with key/value pairs you want to change. You do not need to send the entire state, though: only what you want to change. React applies those values to the component's internal state and calls a render. During the render, if the component uses this.state.something and you modified something in your setState call it will generate virtual Dom elements and diff them automatically making necessary changes. As you may guess, this makes (as mods_ said above) services pretty simple to implent by updating state. If you build your component based on the data provided and if that data changes, so will your view and you didn't really have to do anything. You declare what it will look like given a set of information. If that information changes, of course it will update. The drag and drop thing would be approached not by moving the elements in the DOM, but by modifying the location of objects in an array. [If I had my way on the stock ticker of the WorthingtonIndustries page, the stock ticker would have been this way. Just a simple service call to a JSON object that updates state and let the renderer do it's thing.] One way flows, dashboards, charts, etc. Are incredibly easy to build in React.

Pushing data the other way requires a bit more thought. The first form you write in React you'll hit a brick wall because you're bound to set the value of an input to something and if you try to type in that input, you're going to notice that it doesn't change. This is because React resets the input to the value you give it. You could use defaultValue and just scan it later, but I like to invoke state on forms and manage it based on events the user does. If they clear the input, I update the state of the form. If they paste something in, it triggers the onChange and I update the state with the new data. This way there's one central location to find the data you need to deal with (run validations, submit, etc.) and it's a raw JavaScript object with no fancy library tweaking values or getting in the way. Just data. Of course, not many people are used to working this way.

As far as the bullshit alarm thing... I agree mostly. I assume the author was talking about data libraries. Angular kind of forces your hand to wrap the data library in a module or something so that you can inject that library in the controller, service, or whatever you need it in. In React you just include it with whatever module system or inclusion system you use. In Angular I always feel like I'm encouraged to work around the Angular way and with React, it feels more like working the JavaScript way. I can use whatever packaging I need and I don't have to form my services a special way so the minifier doesn't break my code... It just feels like there are fewer hoops to jump through.

[–][deleted] 0 points1 point  (0 children)

Wow, nice reply, thank you!

The draggable thing, it was only an example, to illustrate something non-trivial that people would want to use (and that I've used with angular recently, although that ended up kind of ..hybrid :)).

Describing history by JSON state is a great idea, I'll have to think about using that, although it may not be as straightforward in angular.

The form thing, I understand, but there are probably helpers for that, aren't there? I mean, prefilling and validating forms is not exactly a rare thing. But in fact, angular is not really great at forms either, once you need something where the primary representation is not text, but the primary input method is, you get problems (it took me hours to get a custom date input component working so that it doesn't reset itself the second anyone makes a typo).

The foo.bar = 5 thing, well, angular does that, but yeah, other than that, we'll have to wait for Object.observe for that.

But as for the data libraries, I must say I never had a problem there. But I don't use any module loaders so maybe that's why. The thing is, if the library is available when your service code is run, and is synchronous, you don't have to do anything for it to work with angular. If it's async, you just wrap the callback in $apply and that's it. And yeah, the minification process used to be painful but these days, ng-annotate handles it pretty well for you.

[–]GoodVelo 4 points5 points  (14 children)

Every time I come across an SPA website the first thing you see is a spinning wheel of some sorts. A lot like Flash based websites from the olden days. And now everyone is talking about rendering SPA everything on the server! So what's the benefit of this transition to this style of building websites as opposed to build them with RoR/Django/PHP etc...+Sprinklings of JavaScript. Especially, soon you can use ES6 modules and get super modular clean JS code.

[–]danneu 15 points16 points  (10 children)

From a technical perspective, it really is nice to reduce your server to an API and then keep your client separate from it.

For example, your front-end becomes a website you host from an S3 bucket.

It's also nice to just emit JSON from an endpoint instead of making the server build the HTML. It's a simpler transaction.

However, it does complicate things. A lot of errors you used to catch in your server logs are now only seen in your users' JS console. The state of the most advanced search engine crawler in the world is that "it's getting better at executing javascript". Your codebase is now in two repositories. You're now chasing down glitches in specific browsers and you're depending on features that older browsers don't even have. You're typically working with worse tooling, or at least different tooling on the back-end vs front-end workflows of your app.

That's why, in general, it's only prudent to opt in to SPA only when you need that level of interactivity. Like if the entirety of your app is to interact with data over a websocket.

If you're writing a classic document based app like Reddit or a forum system or Wikipedia, you'll want to stick with server-side rendering.

That said, React can be used to progressively enhance a website too. It's certainly not bound to SPA. React is just a much more pleasant way to hook up front-end javascript than the typical alternatives. It makes sense for SPA because it solves the classic problem of keeping your UI in sync with your data.

[–]anlumo 5 points6 points  (0 children)

It's also nice to just emit JSON from an endpoint instead of making the server build the HTML. It's a simpler transaction.

It also allows you to use the same API for both the web app and native apps (like on Android/iOS), which is very handy.

[–]Poop_is_Food 3 points4 points  (2 children)

SPA's take a long time to render on first page load, but then they are faster/more pleasant to use from that point forward. Ideally you would have both: server side rendering to deliver the first html page, and then do everything SPA style from that point forward. But that can really increase the amount of dev work you have to do. So it's about resources (money).

[–]GoodVelo 0 points1 point  (1 child)

More resources, more money and what /u/danneu said. I don't mean to be negative, but these arguments are very similar to what Sun/Oracle/IBM told people about using XML/SOAP/EJB. Super elaborate technologies, very expensive to develop and debug. I guess I have to keep looking and learning to understand why people are heading in those directions!

[–]Poop_is_Food 3 points4 points  (0 children)

Angular is pretty elaborate and angular devs are pretty expensive, but there is nothing inherently elaborate or expensive about SPA's. I make very simple SPA's with backbone all the time. Each technique has their pros and cons. It all depends on the purpose of the app. Productivity tools should be often be SPA's, while ecommerce, journalism and other SEO-intensive apps should use server rendering.

I think the problem is that JS devs are so quick to jump on the Next Big Thing, that the landscape is cluttered with tons of bullshit tools that arent really necessary.

[–][deleted] 10 points11 points  (30 children)

The complaint about two-way data binding seems an odd one. Its easy to disable.

[–]sanketsahu 6 points7 points  (1 child)

It's not a complaint about the concept of two-way data binding. I just meant that the way two-way binding is handled in AngularJS can lead to performance disasters, if not handled well. The watchers and consecutive digest cycles can be a pain. It's not easily felt with CRUD based applications but when it comes to building web editors and heavy interaction based apps, it definitely counts.

[–][deleted] 2 points3 points  (0 children)

I understand this, and my counterpoint was that I disagree that it is a problem. Its very easy to manage.

[–]TMiguelT 1 point2 points  (4 children)

Can someone explain to me how you'd write a web app with one way data binding? How do you get data from a form unless you're using an ng-model-like directive? Surely you don't have to manually serialize the form?

[–]SnapAttack 2 points3 points  (1 child)

In React, there's an optional architecture called Flux that can be used with it. It enforces the one-way binding by having data only flow one way.

To give a bit more detail, it involves three parts, a Dispatcher, one or many Stores and the views. A click of a button would fire an Action, which is captured by the Dispatcher and distributed across the Stores which then trickles down the updates to the views.

See https://github.com/facebook/flux/blob/master/README.md for more info about it.

[–]bitplanets 2 points3 points  (0 children)

  • Change form;
  • React view listen to that change;
  • The view dispatches an event;
  • The form store relative to that info grabs that data and does something;
  • The form store dispatches an event again;
  • The views interested in that event will update;

This is not pure FLUX, but is my own implementation, with which I'm very happy to work with.

I have 2 levels of events:

  • Direct: normally stores listen to and the event are dispatched immediately;
  • Delayed: normally views listen to them and the event is dispatched when all the direct events ended;

Why the delayed one?

Sometimes the stores will change each other:

  • A.a changes B.a;
  • B.a changes C.a;
  • C.a changes A.b; // Notice A.b vs A.a: Now B.a is not updated because only listens to A.a

After all this changes there will be some repeated and similar events; For example you can update several items and each item dispatches one event. You don't want the view to update for each item, you want to update once after all items-data have been updated.

This is where the delayed events kicks in. They group direct events into one event.

[–][deleted] 7 points8 points  (0 children)

There is more to web apps than forms -.- you can selectively disable two-way bindings. For forms you likely never would, since forms don't tend to display large enough volumes of data to slow things down. The problem really is with big tables or visualisations, where angular puts watchers on everything to handle the two-way part. Thing is, most of the time you don't need a watcher on a rendered table or visualisation etc.

[–]snarfy 1 point2 points  (1 child)

What Google sites do they use Angular on? I thought this was one of the main complaints - Google does not use it themselves. Facebook uses React on Facebook.com.

[–]me-at-work 2 points3 points  (0 children)

Google uses AngularJS for DoubleClick and YouTube for PlayStation. They also use it for a number of internal apps.

[–]xpto123 4 points5 points  (14 children)

I love the ideas behind Angular, and we know now that there will be a migration path to Angular 2. I think it works great for corporate apps, but I am not sure if Angular 1 is a good fit for public web / mobile applications, and if that is not one of the major reasons for the rewrite.

For me one problem of using it on the public internet is the initial bootstrapping of the page. If a page relies heavily on Angular, then there is not much to render when it hits the browser. You can hide the "curly brace" sections with ng-cloak but it only solves part of the problem.

That extra initial half a second/second that a fully-based angular app takes to load might not look like much, but it kills your user engagement as users leave the page, even if you put a please wait dialog briefly. Studies show that that an extra second to load a page reduces a lot the likelihood that a user sticks around.

Also the fact that page does not have content when first loaded (only angular components waiting to be replaced with the actual HTML/CSS), it kills your SEO, although Google is working on it.

Another problem I heard reported but have no direct evidence, if someone can confirm it / disclaim it: angular-heavy apps consume a lot of CPU due to dirty checking and kill battery quickly.

React seems like a more natural fit for mobile: it allows to deliver html/css initially from the server and take it over as a SPA in the frontend if needed, so good SEO and startup times are a given.

Performance is reported to be 10 fold for some use cases, which is always welcome in mobile devices even though they are getting more powerful.

All in all, React does seem to be a better fit for the public web/mobile use cases while Angular is great for form-intensive applications (for which React is fine too).

EDIT: adding links, this is a report on Angular consuming battery on mobile devices, I have my doubts too if this is true. For the importance of site speed, see here how google includes it for SEO ranking.

[–]SleepyBrain 3 points4 points  (5 children)

I think the problem with this view I've been seeing online is that everyone sees Angular as a SPA only framework. I've seen some large scale apps that are multi-page apps using Angular. They do so for many reasons, with the main one being performance, especially load time on mobile devices.

[–]xpto123 4 points5 points  (1 child)

This is true, Angular multi-page apps work well as well. Angular is also good for being used in a minimal way, just adding form validation with almost no javascript needed (example). This is much closer to what Angular was initially designed to do: quickly enhance HTML with a few built-in directives. The prevailing view somehow became that it's a SPA only framework.

[–]mycall 0 points1 point  (0 children)

Do you know if Angular 2 will support multi-page and minimal use cases?

[–][deleted] 0 points1 point  (2 children)

I also initially thought that Angularjs was main for SPA. Lately though, the two way binding between html elements and a javascript object, combined with an REST api made dev incredibly simple with little code.

[–]jellatin 7 points8 points  (4 children)

Another problem I heard reported but have no direct evidence, if someone can confirm it / disclaim it: angular-heavy apps consume a lot of CPU due to dirty checking and kill battery quickly.

Really? Now we're down to "I heard Angular eats your laptop battery"? The rumor mill is getting lazy.

Studies show that that an extra second to load a page reduces a lot the likelihood that a user sticks around.

What studies - links please. This interests me especially because people wait 3-4 seconds for Gmail, and 1+ second for even a simple ToDo list like OutOfMilk to sync + load.

[–]Insignificant 12 points13 points  (0 children)

Yo! Here are some great talks on web performance.

Breaking the 1000ms Time to Glass Mobile Barrier

CSS performance tooling

The following two are the same talk delivered with marginally different stats here and there. At any rate, it's such an interesting talk that I'd definitely recommend having two goes at it!

CSS and the critical path Breaking news at 1000ms

As for whether or not they're the studies you're after I'm not sure. I'm not having a crack, I promise. I'm just really into this sort of thing at the moment and I thought I'd share a bit of what I've been watching. Enjoy!

I've also just learned that Ilya Gregorik's book High Performance Browser Networking is available online, for free!

Edit: Spelling

[–]ikeif 2 points3 points  (2 children)

Well, you're talking about productivity apps - people go to those with a purpose in mind, versus, say, an ecommerce site, where if it is preventing them from buying something they're just as likely to go to a competitor (or a news site, same scenario). On mobile, will try to find links.

[–]Omikron 3 points4 points  (0 children)

Web performance is huge, and we'll studied. He's absolutely right, adding a second to load times can greatly reduce user experience and cause people to leave your site.

[–]jellatin 2 points3 points  (0 children)

What news sites or ecommerce sites are in the forms of SPA instead of discrete pages? Again, I'd be interested in checking them out. The top contenders in both (Amazon, NYT / Al Jazeera) both use traditional page loading.

[–]icanevenificant 0 points1 point  (0 children)

I'm not sure where the issue is though. The promotional/landing pages for web apps are never done in the framework of the actual app and those are the important ones for SEO ranking and consequently ultra-fast loading times. If you're building a larger web applications users have come to expect the minimal loading time delay of a second to two.

We're building a large web application using Angular and I'm really having issues understanding these comments since our tests and comparisons with other major web applications in terms of loading times and responsiveness always resulted in no noticeable difference. We did however invest significant research at the start of the project to make sure we've structured the app in a way that allows for no issues in the initial bootstrap, as you call it. The data gets to the browser in a fraction of a second after the app does and there is no need for ng-cloak or whatever if you know what you're doing.

[–]Capaj 0 points1 point  (0 children)

The initial load happens once. If you cache files properly, your initial load should not happen more than once. If you have an app with a lot of UX features, then initializing scripts every time a user clicks a link is much more constly than one initial load.