React is by far and away the best the market has to offer right now. From my perspective client-side applications are a solved problem thanks to React.
React is by far and away the best the market has to offer right now. From my perspective client-side applications are a solved problem thanks to React.
React completely changed the way I thought about rich clients. It took me a little longer than 2 days, I went into React with an absolute hatred of anything Javascript and came out 2 weeks later loving it. There is something to be said for a library that can wash away over 10 years of built up anger for a particular technology. It's not just another revamped library thrown into the frying pan, it's a complete rethink of how rich clients can be developed almost effortlessly with code that anyone can read. When I got into react, all I could think was "yes, this makes sense, this is how it should have been all along." Moving into the future I expect most libraries will unify under the concepts introduced by React in the same way that most web applications frameworks are different flavors of MVC.
Angular has a void with the lack of a useful enough eventing solution - $scope eventing has specific use cases, but you don't want to use it as a general event bus, mainly due to performance. This is important for Angular since you don't want to couple modules together with hardcoded state keys that you may want to alter in different applications.
Flux does offer a way around the eventing problem at a lower level within React components, but on a higher level, there is no application level of control - you have to construct exactly the control you want, which while liberating, also is an easy way to create a hole in architecture when designing an application if you're not careful. Angular exposes that problem directly in many ways (for example handling transitions between two urls in the application), as well as forces thinking about module dependencies with dependency injection.
HTML mixed in with JS via JSX is also an abomination, that originally made me want to run far away from React when I first looked at it. I'm not a huge fan of it still, but it's not an extremely terrible thing as long as you keep higher level templates slim, which React forces you to do in order not to have huge chunks of HTML mixed in with complex JS...although I'm sure there are developers out there who do it anyway (just like there are plenty of Angular developers who will toss plenty of jQuery in an Angular controller).
I've found that using a publish/subscribe system for communicating between components makes them more loosely coupled and modular. In most cases, the components I've written are naturally somewhat slightly coupled so I just pass around functions as props from parent to child components.
> HTML mixed in with JS via JSX is also an abomination ...
Totally agree. I use the default React.DOM elements instead. I find them more transparent and easy to read, and manipulation of these are much easier using the map, filter, folds etc.
I agree - my company is going to open source an event machine for Angular sometime in the next couple of months which should address this hole.
> Totally agree. I use the default React.DOM elements instead. I find them more transparent and easy to read, and manipulation of these are much easier using the map, filter, folds etc.
Unfortunately it doesn't seem like React documented React.DOM :( . I would rather just use HTML, but I would rather have it in a separate file. Perhaps a build tool for grunt/gulp where you can register keys with the path to the template being the value, and the tool converts the value into the React.DOM elements would be a good idea.
React.DOM.div(), etc. are part of React's public API -- if we didn't document them, that's a mistake.
Edit: As a note, I did find out how it worked by doing source code diving two months ago.
Why?
Ha! It made sense to me. It was very easy to explain its purpose and it is entirely optional.
- this feels like it is a key conceptual difference but I'm not clear on what this means.
Never got beyond all the directives, digests, factories, services, scopes, dependency injentions, all the ng-* tags and so on. That is a lot of terminology for something that is supposed to make developing web appliclations easy.
Granted I am not a Web UI developer was just curious what everything was excited about.
Maybe all this complexity just makes sense to someone who already did all the more complex stuff wiht jQuery? Not sure.
Anyway React made sense to me. The whole data flow ideas, minizing mutable state and inter-dependencies between components, VDOM and even JSX.
So I like React a lot better.
It's really not that huge of a jump from Angular 1.0 to Angular 2.0. Small example:
<button ng-click="addTodo()">+</button>
becomes
<button (click)="addTodo()">+</button>
and
<div ng-controller="SantaTodoController">
literally becomes
<div>
Getting the advantage of 1 framework that's batteries included + universal (i.e. taught in CodeSchool, Tuts+, etc.) vs. an eclectic selection of libraries all over the place, gives Angular an advantage IMO.
Really the choice comes down to whether you're a "single big framework" or "lots of little libraries" type of guy. The former should go with Angular2, the latter with React, IMO.
React is very cool, no doubt, and I use it in my own app, but let's not get ahead of ourselves. React is far from perfect:
- the Virtual DOM is a leaky abstraction: you sometimes need to get your hands on a real DOM node: http://facebook.github.io/react/docs/working-with-the-browse...
- if you're updating the virtual DOM from anywhere other than React's event loop (for example from a setTimeout() or XHR callback), batching doesn't happen properly which can lead to inefficiency. Needing to be aware of what runs inside a React event loop vs. what doesn't can add application complexity. More info: https://groups.google.com/forum/#!topic/reactjs/LkTihnf6Ey8
- writing manual event handlers is a somewhat more manual and less expressive than some of the two-way data binding approaches like Knockout.js or Angular.js.
It seems to me that the integrated approach of angular isn't answered by react.
You are correct that React alone won't replace Angular, but with other tools (Ampersand, Flux, etc) you can use the pieces that you want and put them together. It's the difference between a library and a framework.
Now react may help with the performances of refreshing the dom in that scenario, but so far i didn't encounter that issue myself.
I do find that the flux model makes more sense to me. Flux is a set of best practices, they use React for the rendering/view portion, and since their talks there have been several implementations of the workflow. Some using Ampersand or Backbone, others implementing their own pieces. Now Facebook has been releasing their own implementation...
It's all pretty interesting.
Router - Backbone's router, page.js etc
Web service querying - simple jquery ajax calls or you could use breeze.js, pouchdb etc
Unit testing - React has one built in, but you could use others too.
And there you have your answer :)
What the JS people don't seem to grasp is that I don't care how many libraries are out there. I care even less about the incompatibilities and the different release cycles of all those libraries. By now, I hope you understand that my interest in maintaining and integrating all those into a coherent system approaches zero.
I am a software engineer and not a JS technologist. The front-end is just 1-10% of any serious system and yet, in the JS world, it takes 90% of the time building it and maintaining it. It just doesn't add up.
Imagine 10-15 years ago if we had to build GUI apps by mixing and matching 100 incoherent libraries, that in 1-5 months some of them will be obsolete, abandoned or whatnot. This is what JS has accomplished today and people just take it for granted.
Now I am sad and I will return to my crying corner.
While it is true that there are far too many frameworks that come and go in JS land, you can find very stable, well-maintained and clean libraries too. For anything that's essential to your stack(DOM interaction, routing, UI elements etc), typically you'll find multiple well tested and stable libraries. Atleast, that has been my experience.
With well designed libraries, integration is rarely a problem. They are designed to be interoperable and don't make too many assumptions about things they aren't good at.
It takes a little bit of work upfront, but I find it's far better than relying on monolithic frameworks that tries to do everything under the sun(and usually fail).
Switch to React, I guarantee you that your front-end dev time(and overall) dev time will drop drastically to 20% :)
For every well maintained JS "technology" there are 100 others that aren't and they occupy the same playground. Evaluating them takes more time than one might think and at the end of the day, what you choose carries a huge risk. Yes this also happens in other aspects/technologies, but with JS stuff the risk is almost always higher.
A word about monolithic systems; You give too much credit on what a JS framework does. It's just one job. Do you ascribe the same term to GTK or Qt for example?
To be honest, React seems decent. I don't necessarily disagree with you, you just touched... a nerve of mine :)
If I ever have to evaluate JS frameworks again, React will have its turn then.
Cheers
Wow, I want you to come work for me for a week. The front end is what interfaces with the user - your client - the one whom is paying money. You may hate JS, but it is the tool that we use to build interaction.
I don't want to underplay the importance of the front-end, or in general the interfaces and what that means for bringing value to a product.
But however you spin it it's not the core technology. You could make the same point you made, by saying the same about the marketing/sales department. Yes, it's how you bring customers and without it you'll probably fail to reach a large audience. But again, it's not the core of your product.
Also keep in mind that mobile platforms(which are quickly becoming much more important than the web) also have a user interface. Take a guess at which of the 2(web/mobiles) are more costly to develop and maintain. The web, by far. That can't happen for much longer, that's all that I'm saying.
Now what would be interesting questions though are: 1) How many people work in the backend and how many work in each of the respective front-ends.
2) Suppose that you had 2 front-end interfaces, angular(for the web) and an android app(it could be an iPhone app, it doesn't matter). How many backend devs would need to know or actively interact with the angular front-end and how many would need to interact with the android app.
In my case, none of the backend people(a lot) need to interact with the mobile codebase(2-people team for every mobile type), while all of us need to help or interact with the web front-end.
I see similar scenarios with most of the companies I interact or know about. The mobile team is almost always autonomous and can accomplish a lot with just a few people. While hords of people are thrown into the web frontend, even if it's not their primary specialty. Hence the need for fullstack developers. Why? Because the JS ecosystem sucks and we still don't have a real integrated solution. I hope that this will change, preferably before I retire.
More often than not, the web frontend ends up being client side HTML/JS and some sort of intermediate middle-end server that hosts that HTML/JS. That way it turns into a fullstack app that does some processing on the middle-end to pass it on to the front-end JS.
You can make the frontend 100% static HTML/JS (and serveable off any static file CDN), so all you have to worry about is the API between them.
Using something that does all that for you is tantamount to outsourcing all the engineering work to the makers of that thing.
If you're given and entire system and just have to put the pieces together according to what the client needs, then you're basically a plumber.
Now there is nothing wrong with that, it makes good business sense, which is the justification you provide, but its not really engineering. Or if it is, it's only a small subset of the problems engineering solves.
Do you think the builders of the Golden Gate Bridge, the Hoover Dam or the Space Shuttle didn't have to think about all the bits and pieces they would need source and bring together into one coherent whole? That's engineering.
Unless you're trying to tell me that people who build e.g. KDE with the Qt framework are plumbers and people who develop with Backbone.js are engineers. In which case I wouldn't want to engage in such a discussion.
Neither Angular nor React nor Backbone are equivalent to KDE or Qt, so those are false equivalencies use to construct a poor excuse for a strawman.
The user agents (browsers) and the web as a platform is the closest equivalent to Qt, since collectively, they abstract away all the differences between platforms as Qt does. Collectively and individually they represent excellent examples of engineering. The problem with them is that the problem they are trying to solve basically changed from what Tim Berners-Lee originally tried to solved. He tried to make a hyperlinked document platform, not an app platform. The web is now trying to evolve to supporting apps while also remaining a good documentation platform.
React would be most closely equivalent to added the paint/draw and retain-mode graphics part of Qt to the web. Flux and its different implementations and the various libraries out are likely equivalent to different solutions for events and data stores available in the Qt ecosystem, but I'm not a Qt developer so I wouldn't know. Those who built react are doing engineering as are those who build with react, it's just that the latter are absolved from solving the engineering problems related to render/paint/layout and retain-mode graphics.
Angular is an attempt to bundle everything together (render/draw, events, data) into one monolithic framework solution, doing reasonably well, but none exceptionally well. Those who built angular are doing engineering. However, those who build with angular are basically doing plumbing.
People who build with KDE and people who build with angular are basically performing the same type of work.
I don't know what backbone is equivalent to in the KDE or Qt world, but I would imagine it's probably some early library/quasi-framework in the Qt world when it was still the wild west and there weren't very good engineering practices and project organization strategies in Qt projects.
I can't believe I wasted my time responding to your logical fallacy.
First of all I stupidly thought that the part about KDE/GTK which is in this comment of mine https://news.ycombinator.com/item?id=8508094, was included in the comment to which you replied. So my bad and -1 for me.
What I meant is I don't think that anyone sees Qt or GTK as monolithic systems and they are about 1000 times more complex than any JS library you could name, as they solve a myriad problems to which JS is oblivious and wouldn't be able to solve anyway.
Contrast that with the web situation today, where they can't even decide which is the view, which the controller or "hey, maybe these don't map very well on the web side of things". Yes I agree about Tim Berners-Lee and the http stuff. But at some point things have to converge into something coherent, because the problem we have to solve is quite elementary, compared to other technologies.
Also if you honestly believe that people who developed KDE and people who develop with AngularJS are performing the same type of work... it just betrays the fact that you're just a JS programmer and haven't seen some real engineering work.
Javascript touches the tip of the iceberg with regards to technical challenge and Software Engineering, so please... just take a breath :)
It creates unneeded wasted work in evaluating and comparing the alternatives; it makes maintenance harder and slower as people moving between projects have to get used to different components and styles every time, etc. Opinionated frameworks have a valid engineering reason for being and staying opinionated.
AngularJS does too much, and nearly all of that too much poorly.
Also pay attention to the new createFactory method which aims to make it easy to separate your changing HTML from the static HTML (which you would have previously used a templating library for)
My recommendation is to not use JSX ever since it breaks a lot of your tooling. The first impression people get is that "Hey this makes my code easier to read", but that is only because JSX introduces the problem that it attempts to solve.
Basically most HTML structures are 80% unchanging and 20% changing (the reason we use templates in the first place). React.DOM was a pain previously because you'd define a complicated HTML structure in Javascript, which isn't really any harder or more complex, but then you'd have all this code that was never changing distracting you from the code that was changing (i.e. your app behavior). JSX fixed this problem by turning all the static bits to html like templates do so it was visually easy to separate from your behavior code. This was the wrong solution because it's over engineered and breaks compatibility with a lot of things.
createFactory essentially allows you to "partially apply" the static parts and get a function that only needs to deal with the dynamic parts (like compiled template functions but for virtual DOM)
Anyways, check out the following links:
React implements UI views and controllers. You write views that know how to render themselves, and then you write views that control them; the latter type of view fulfills the role of the classical MVC controller.
For example, consider how Cocoa works. It's a classical MVC framework: You have a view controller, which mediates between data and views. The controller doesn't know how to render anything, but it listens to data modifications, and sends update commands to the views; it also listens to changes to views and propagates those changes to the data model. (You can also let Cocoa Bindings do it for you, for the most part.)
In a single app, you typically end up with many such controllers, typically one per window, and controllers can reference each other to facilitate communication; also, there are often controllers that individually control just a single view, because it's easier to encapsulate reusable components that way. For example, if you need a text field that autocompletes, you could subclass NSTextField and build this special behaviour into the view itself, but it's cleaner to create a controller that can bind to any normal NSTextView.
In React, you have the same distribution of controllers (some handling big, multi-view layouts, some targeting discrete views), but the controller actually takes part in the view hierarchy: A controller has views as its children. It may not even use DOM elements, but consist entirely of custom view components. And it does exactly the same stuff as a controller would. For example, it may contain this:
<Form>
<TextField label='Name' minLength={3} ref='nameField'
value={this.state.name}/>
<NumericField label='Age' min={0} ref='ageField'
value={this.state.value}>
</Form>
In this example, TextField and NumericField would be generic view components, just like the standard Cocoa views; the controller wouldn't be doing anything view-related like working with the DOM, but it would mediate between the data model and the child views that it controls.This is very much like building out a form in Interface Builder and connecting the actual controls to variables using IBOutlets. In fact, I would argue that there is hardly any distinction at all. The difference is that the UI is declared in the controller. And why not? Interface Builder is separate, and keeps its view data stored separately, because a WYSIWYG editor can't touch code. (Actually, Delphi showed that it was possible, but that's another story.)
The fact that there is a separation isn't actually useful to anyone. You generally cannot edit the view layout without breaking code, and you can't edit the code without breaking the view: They have to be maintained completely in sync with each other. So you might as well just keep the view layout in the same file as the controller. Which is what React does.
As someone working on a team that practices a good amount of separation of concerns, this is patently false. This is more dependent on how good your template language is than anything, but this separation helps to assure that we're not introducing new bugs or the like.
The main arguments for React along what you're saying is that people seem to abuse the "view model" concept. It's rarely as necessary as people seem to want to make it (though again, dependent on template language).
It has nothing to do with how good your template language is. It's simply that a controller's main controller (not talking about partials here) has an implicit dependency on the controller, and the controller has a dependency on the template. Unlike, say, data models, the relationship is not unidirectional.
But really, what is this separation for? What does it gain us? We generally separate stuff out into declarations and files because it gains us modularity ("separation of concerns") and reusability. Data models are constantly reused, for example, as are views. But that one template belonging exclusively to the controller isn't reusable. It's separated out for no particular reason other than the fact that, historically, it has been expressed in a different language and must be parsed and "compiled" separately, so it has not been about "concerns" but about implementation details.
React removes that step, and because the template is unequivocally tied to the controller, there is nothing gained by separating them. The point of React is that the "template" is the component. The component's rendering is intimately tied to how its internal state and data model is wired up because the one half wouldn't work without the other, and vice versa.
(As an aside, in a well-designed, pure component, there is little state and the component is mostly template, anyway.)
(As an aside, most template languages don't even let you validate a template's inputs — that is, declaring that it requires specific named inputs and what their types/structure are. No idea why, seems pretty obvious defensive functionality to me. But React does this.)
Oooh, do tell!
Let's say you created a form, which in Delphi parlance was a surface that could inhabit controls, typically an actual application window. You would get this empty window:
http://www.vwlowen.co.uk/basicdelphi/images/theide.jpg
You would also automatically get a source file containing the class definition for that form, roughly corresponding to a window controller class in Cococa. This class would be completely empty, mind; no init code needed or anything:
http://136513.jakero00.web.hosting-test.net/wp-content/uploa...
(The GUI layout would live in a separate binary "form file" you never needed to edit directly. This file contained serialized objects that you could read and write in code, similar to OS X bundles, except more easily extensible.)
This class would be, by virtue of having the same base file name, automatically linked up with the corresponding form, so you could quickly switch between code and UI.
Then if you added a button the form, Delphi would automatically add a private member variable declaration "FButton1: TButton" to your class definition, as glimpsed here:
http://www.delphisources.ru/pages/faq/master-delphi-7/conten...
The framework would know, from the GUI definition, that FButton1 was that button. You could edit it and move it around in your code, and it would still be bound correctly.
Same thing with event handlers: If you went into the button's inspector and double-clicked on the "click" handler, it created the method for you, and placed the cursor in the right place so you could immediately fill it out with code.
This system made developers insanely productive, because the "boilerplate interactions" were reduced to almost nothing, and all the work was actual work. No "IBOutlet" stuff needed, no manually connecting the variable to the right thing in the GUI builder, and very little setup.
A few more brilliant, deceptively minor details made this even more magical. First, the form you edited was truly "live". Delphi actually rendered real controls in the editor. If you created a control that did custom rendering, it would render like that in the GUI editor, live. Interface Builder sort of does this, but not quite, and custom controls are a pain and apparently no longer supported.
The second thing was the object inspector:
https://www.ibm.com/developerworks/data/library/techarticle/...
Interface Builder has a very poor one; Delphi's felt natural. Every property exposed by a control would be visible there through reflection: Delphi would actually parse properties out of your code. It supported structured properties, so if something was a TFont, it expanded into sub-properties for font name, font size and so on.
If you created a new class TGradientButton or something, and exposed two properties FromColor and ToColor, they would show up in the object inspector, automatically, and since these properties would be something like TColor, it would know to display an RGB widget for them.
You could also register custom object inspector behaviour, so that, instead of FromColor/ToColor, perhaps there was only one property "Gradient" of type TGradient. Your custom object inspector thingy could then render a gradient editor for that property.
XCode + Interface Builder is about 10% of what Delphi was. I say "was", it still exists, but I haven't touched it since around 2000-2001. It's insane that Delphi 1.0 in 1995 was more powerful than XCode + Interface Builder today.
(I suppose it lives on in the Visual.NET tools; after creating Delphi, Anders Hejlsberg joined Microsoft and created C#. But I haven't used any of it.)