Redux effects and friends are simple too but suffer the same issue, they're so functional that they can be hard to reason about. You really need higher level abstractions to hide that stuff or it gets unwieldy fast.
I think it's the typical 80/20 – hard things are easy with React/Redux, easy things are sometimes hard.
After experimenting with React I'm now using angular2 for my project and apart from some bugs that are left I'm quite happy with it. Architecture-wise I put all state (serializable or not) in multiple-independent plain JS service objects which are injected into the view components through ng2 dependency injection. And they expose their state through observables, which together with things like async pipes makes reactivity really easy.
It definitely has a learning curve, but the very simple data flow makes it pretty straightforward, once you've learned what each layer does.
The section on JSX & the React.createElement API is a weird diversion, because these aspects are so unrelated to the high level code structure complaints that they belong in a different article. Putting that aside, this section seems unfair at best. Firstly the JSX syntax is disregarded due to verbosity[0]. Okay, not to everyone's taste. However the author then goes on to making a comparison between React's createElement/createFactory APIs and the hyperscript-helpers npm package, which is incredibly uncharitable as the former is a performant, low level API intended for building ergonomic APIs on top of, and the latter is a high level, ergonomics-centric API.
Redux is a small library, which needs to be used underneath application-specific abstractions to avoid boilerplate. Not everyone will want to come up with such abstractions themselves. I can certainly see the value for an ergonomic, high-level, Rails-like project on top of React + Redux. Maybe that's the article the author should have written.
[0] I would argue many developers actually find the verbosity of JSX helpful when dealing with large trees of components, as compared to nested function calls. The fact that JSX closing tags repeat the tag name is key to this.
He also doesn't mention the learning curve, and I'd argue that function calls for DOM is less beginner friendly. It's pretty easy to mentally map a render function to its output because they're so syntactically similar.
In fact, as a general comment, the article actually solidifies my choice of using React precisely because it's 'verbose' in the right way: it makes working with something (inherently?) messy explicit, and as a result much easier and pleasant.
As I learned how to work with React I've had quite a few moments where I got frustrated trying to get something done, only to realize that I was doing it wrong and that React was 'coaxing' me into doing things right. Very often, without trying, I'd do things in a way that suddenly made things 'click', where in the past my solution would've turned out messy, and where in the future even using other libraries/frameworks and applying what I learned will lead to a better result. I really think the 'pit of success' idea applies (which was mentioned in the initial video presenting React).
It's more than uncharitable; it's nonsensical. There is quite good hyperscript support for React. If hyperscript is so great that being able to use it with Cycle is a plus for Cycle, then logically it's also a plus for React.
I haven't explored Cycle.js or Elm, but a few comments on the React/Redux side as I've recently adopted it at work and have found it to be a huge pleasure to work with. There does tend to be a lot of syntactic boilerplate/wiring up of things in Redux which is definitely a bit of a drag, but the most important thing that Redux has done for me is make data flow very clear and easy to trace and understand. Even with Facebook's impls of Flux, and Backbone before that, data flow was very tricky and cloudy at best.
As for the criticism that setup has a lot of moving pieces, I sort of agree, but I found myself up and running in a few hours after reading the (incredibly well written) documentation and within a few days I was already more productive than I was previously without Redux.
Elm also gets out your way by having immutable types built-in, signals built-in, “dispatcher” (Mailbox) built-in, and ADTs for action types built-in. The experience is great for a developer and the initial setup is quicker.
Built-ins are a tradeoff just like anything else. Redux gives you enough to get going, and has a strong ecosystem and community of libs that most people will use (react-redux, thunk middleware). Built-ins might help you get started faster, but maybe that doesn't fly for a company of 100 engineers where use cases vary and customization is important.
Lastly, the author claims Cycle.js lets you 'focus on features'. From past experience, this makes it sound like there's just a lot of magic and it's easy to get lost in it all (see Rails). This may or may not be the case with Cycle.js, but that is immediately my gut reaction. I feel Redux gives a pretty powerful philosophy and clear way to handle front-end apps that can scale well to larger apps. If there are some things Cycle.js is doing well over Redux, I want to hear more about those! The arguments against Redux without that context feel pretty weak.
i happen to agree with these points in many regards, so perhaps I'm a poor reader and merely projecting...
but yeah, I'm pretty over the militant "a react in every stack" approach... ditto every other myopic temporary obsession... you realize this after a couple hegelian cycles of thesis, antithesis, synthesis... i mean, when yesterdays baby becomes todays bathwater and it's time to throw it all out, or perhaps consider renaming "common sense" that rare balanced mix of functional object-oriented reactive structured aspect oriented programming as a service platform...in the cloud
Handling async events can be difficult and error probe. Observables finally provide a useful pattern to that can be used to effectively manage async operations on data.
React os the poster child because it came first but Angular2 also uses Rxjs (ie Reactive Extensions for JS).
The poster goes to the opposite extreme, "if we're doing functional programming in JS, everything should be functional. Here's what I use, everybody who doesn't also use it is dumb."
Subjective opinion addressed as fact.
Perhaps missed the whole second part of the article, which gives several concrete examples and concerns.
As for Redux, I'm more of a Alt.js kind of engineer. All that being said, Cycle and Elm are totally cool.
The problems that Google and FB is trying to solve at their unique mega scale is rarely the issues that startups and medium sized companies are facing. Flux and Graphsql comes to mind.
For example micro-services are great for Amazon but may add more complexity to tech team that are less than 50 people.
I have already published a <ng-markdown> component to GitHub that can be installed via JSPM and imported as an ES6-module.
The new module and web component standard are going to completely change the nature of how web applications will be built in the future.
Unfortunately, it'll be a few years until both standards are natively supported across all browsers.
Until then, web component frameworks like React, Ember, and Angular2 are the best alternative.
If you don't like frameworks, you can use polymer to as a web component polyfill but I've heard it adds a lot of overhead for what it provides and has some quirks of its own.
Until Elm/Cycle/whatever's next have been around for along time and become established then to pick a framework to base a serious project on you're in the "two kinds of languages: the ones people complain about and the ones nobody uses" category.
Although, to be fair, unlike Google with Angular, FB (more often Instagram) is actually dogfooding React and using it on their own stack. And with react-native they've invested a lot more in React tech than Google has in Angular.
People thought that with Cassandra too. Its not a safe bet to trust in a single well funded engineering organization.
Cassandra really only survived because Netflix, Datastax, Apache, etc. picked up the torch when FB dropped it.
That said, its still safer than the OP's suggestion.
As a solo developer trying to bootstrap a startup I started out 8 months ago with React, I have had a reasonably good experience with React itself. For a pre 1.0 project it's surprisingly stable and once you figure out what you're doing I've been able to move relatively quickly.
The big holdup has been the supporting libraries. Some have been an absolute mess but the solution to that is that once I got it working, just don't touch it and don't buy into the promises that it's always going to be the next version that solves the issues. I didn't opt for Redux and went with Fluxxor instead which has worked reasonably well but I kept getting errors and ended up forking it to fix the problem. I'm not going to go back and use Redux for everything because someone told me it's better.
I am now on my 3rd build tool over this timeline. I am now on Webpack because people kept promising that the next one would be better. I struggled to finally get React-Hotloader to work and occasionally it works but most of the time I just get Invariant Violation errors and have to do a full reload. I had to jump through hoops to get this to work and enable CORS etc for virtually no benefit. It will almost certainly be my last build tool for a while.
The pattern with JS from my viewpoint has been to overhaul entire libraries because it's not quite right. It seems that what these developers don't realize is that when you solve one problem you often introduce another. Once you have a working solution there isn't really much incentive to change things. This guy laments that there is not a good way to do pure JS instead of JSX but you know what? JSX is fine. I already need a build tool to use ES6, and as long as you are consistent you shouldn't run into too many issues using the pure JS solution that comes with React if that's what you really want to do. JSX might be ugly but I would rather just deal with the ugliness and settle for good enough then keep creating extra work for myself in search of perfect.
My goal is to build an app. I don't have the time or inclination to try out libraries like cycle or elm every time someone brags about how perfect they are just because they might provide me with a little benefit in terms of ease of development. I am perfectly fine with sitting back and reaping the benefit of other peoples' WWE-style back and forth even if I have to wait a year or more for things to stabilize.
Additionally, he presents the framework/language Elm, a library he is not really involved in, as a superior alternative.
In Elm you have to hack the system to give the focus to a single input or use an external lib... See https://github.com/evancz/elm-architecture-tutorial/issues/4...
The idea of Elm (http://elm-lang.org/) excites me greatly but then again what's to say that Elm will be dead in a years time? My question, is there a framework out there that mixes the better parts of React (virtual dom, large community), the idea of functional programming and a server side aspect to build the back end in one package?
I realize that's a suggestion that will only apply to a relatively small niche in comparison to many of the frameworks discussed, but since I'm a part of that niche... :)
But yeah, you probably should be using something better than ES5. So is it Typescript? Elm? Clojurescript? etc? I think Elm is out. And while the others are probably good, long-term solutions, why learn a new language if you can get more or less the same feature set with something that already integrates with your build-tool/stack? Seems like a no-brainer to me.
And then once you have that, do you really want a client-side "framework"? For some problems maybe... but I feel like if you solve the basic problem of language, that question becomes a lot less relevant.
Just seemed like an appropriate place to vent my own thoughts on the subject lately. I get there are plenty of people that don't care for or aren't excited about Scala for one reason or another, so I'm not attempting to persuade anyone it's the right choice for them.
How do the Play framework and Scala.js work with each other? Can I easily write an application is Scala and then sprinkle Scala.js around to perform AJAX data fetching for example?
Sounds like there's an opportunity to package a lot of those things together into a single Rails-like "opinionated" package.
I think only Ember has been able to have a strong set of conventions, mostly thanks to ember-cli[1]. I consider it the Rails of JS.
That said, I am looking into nwb[2]. Looks fine for personal projects.
It's not perfect, it feels a bit big sometimes, but everything I need something to build a feature quickly it's there in the framework or the build tool, and that's good enough for me.
I enjoyed learning them and am efficient using them but now I'm not so certain that it's the best choice for a team with developers of different skill level and experience. Once you throw in React-Router even my days in Angular 1.x seemed simpler.
With react, I can explain, quite simply, that it's simply a function: (state, props) => HTML . That is elegant as fuck. There no dirty checking, no two way binding or unintended side effects by cross-referenced observables.
React-Router is only necessary if you want to build a SPA. Then you learn how it works, or you use some other router (like Redux-Router). It's great. You actually understand how your code works.
It's a steeper learning curve up front, but you learn and you become a better developer as a result.
The component tree is a directed acyclic graph of single-inheritance relationships. Services are singletons that can be injected into any component to share state. Dirty checking follows the tree (ie the DAG) of inputs/outputs specified in the component metadata so there's at most O(log n) comparisons per update. To make dirty checking efficient favor immutability because it's quicker to superficially compare references than it is to deep check an entire data structure.
Anything that's inherently asynchronous is handled via Rxjs observables using either a one-to-one or one-to-many publisher/subscriber model.
As for Angularjs. Who the hell knows? Dirty checking, crawls the graph of relationships until the dirty checker gets tired. Services are kind of like singletons, I think. Factories try to mimic the borg/prototype pattern (because, reasons...) to provide singletons that share a reference to a common closure. Who the hell knows what providers do, maybe provide an instance that acts like a static helper class? Directives are magic, really complicated and painful to use magic that preprocess the HTML, who the hell knows when.
That said, I imagine cycle.js would be even more complex to learn - with this recent race to "FPR all the things!".
Therefore for me the most important metrics for a web framework are popularity and ability to deal with complexity. Hoping though that I get enlightened by another framework one day...
Want to re-evaluate your whole base of knowledge? Teach programming to adults who have never written a line of code before. Wow, the things I thought I really understood. :D
He's probably right about Cycle though, for some devs, on some projects. Then again, I've spoken to people who went all in on Cycle and got burned, and found it inferior to React. A guide to when you might prefer Cycle to Redux would be interesting, but this isn't it.
(And as others have noted, his comments about JSX versus hyperscript is quite odd. React is not tied to JSX, and you can easily use hyperscript with React if you choose. It's just that people don't, because most people don't find hyperscript as awesome as he does. Which is sort of the article in a nutshell; "X is better than Y because I like X!")
From memory, it was based around the way the redux patterns is very top down with a single state atom, smart reducers, and dumb components, but the cycle pattern is very bottom up with smart components and no centralization. So as your app gets complicated with cycle, you can start to lose track of all the different streams and start to struggle with figuring out what your app is doing in total.
Mind you, they may have just been doing cycle wrong, and you have to take people complaining about their tools with a grain of salt. But the impression I got is that cycle is not a magic bullet that makes large, complicated apps with difficult state management problems easy to code, any more than redux is. Cycle is great when you start looking at redux and go "oh shit, I do NOT want to start coding these reducers, can I just break it down into tiny parts and solve each one on its own", but redux is great when you start looking at cycle and go "oh man, I do NOT want to try and figure out how all these bits work together, can I just put all this crazy logic in one place?"
(Disclaimer: Have never used cycle; just talked to some people who have.)
(I vaguely recall Ractive.js doing something similar, which led me to make the opposite choice and use that instead of React.)
I haven't tried Elm or Cycle in production but think our code would be much easier to work with if it were written in any of those that it is today with React. There might be other problems like stability and some special features we might miss or the learning period might be much longerthan I think but overall both alternatives looks better to me.
This is yet one more article that makes me want to try Elm. It has been mentioned more and more often here, but I don't know if its actual usage has grown as much.
The inversion of control that happens with Cycle.js makes it really easy to compose components together. At first it feels weird to not manually specify event handlers (e.g. onClick) in DOM-generation code, but as a result there's much less embedded opinion on how the component be should be used. Instead each component simply returns a collection of queryable observables, which is extremely flexible and adaptable.
It's also cool how components have the exact same function signature as a full Cycle.js app, so you can think of your app as being composed of several mini-apps. It's very clear Cycle.js was designed with composability in mind from the start.
~8k min. No build tools, no dependencies. Extremely fast [2], composable, isomporphic. JSONML [3] superset template syntax. it's plain js all the way down.
[1] https://github.com/leeoniya/domvm
This is but one of many reasons why having all externally visible parameters be props is a good idea in React, so you should probably do it whether or not you want your components to be reusable.
> In Cycle.js you can omit the props object. Since props are always an object and children are always an array, it’s obvious which parameter is what:
ul([
li('Foo'),
li('Bar'),
])
That's a lot cleaner than JSX. Kudos.The syntax is slightly different though:
h('ul', [
h('li', 'Foo'),
h('li', 'Bar'),
])
Otherwise the same advantages as the author listed when using Cycle, eg, props and children are both optional, etc. ul [] [
li [] text "Foo"],
li [] text "Bar"]
]
Took a while to "get" it, but now I really like it.(`ul` and `li` are functions that take two lists - the first is a list of attributes like class or ID or whatnot, and the second is the inner content... text or other elements.)
ul [] [
li [] [text "Foo"],
li [] [text "Bar"]
]1. Updates are O(N), where N is the size of your virtual dom tree.
2. You have to manually keep track of dependencies within your code, in order to trigger updates.
#2 is flat out not true unless you decide to ignore all of the documentation and have your render function depend on something other than the state and properties of your component.
I find it odd that after 5 years developing multiple products with npm, node.js, meteor.js, flask + uwsgi, angularjs & react that now I'm back to just using Laravel + jQuery to build my single page application with REST api. It's easier and cheaper to find skilled php developers and learning jQuery is not a problem.
It's the 2006 formula but it works so fucking well and so much easier. Scaling is going to take work regardless even on AWS so now I prefer reduced technical debt and maturity of tested and true technologies.
I know this will get me crucified by mid 20 something hackathon hackers but this is just based on my own experience rather than blog articles. Something I learned very painfully through neophilism rampant in the industry.
Unless you were in a large design agency it doesn't make sense to add the abstraction overhead for majority of today's single page apps can be pulled off with jquery libraries from unheap.com
The reality is that many species can coexist in the same habitat. You don't have to pick just one. Cats don't have pincers, but does that have to mean lobsters are superior? Nope.
I just don't see an incentive to move yet, I didn't last year and the way things are going I might not for another year.
Then maybe cycle.js could come with a more minimal implementation rather than having to bring in a library with a gigantic footprint and 100+ operators (https://github.com/Reactive-Extensions/RxJS/blob/master/doc/...)
I feel like I'm still waiting for the Holy Grail of JS frameworks/libraries.
- ES module loader - native web components - native observables
That's the gist of what all of the latest generation of frameworks aim to provide.
The next generation will use these and focus primarily on reusing front-end application logic across platforms. Ie Mobile, IoT, Desktop, etc. This is already happening to some extent.
Maybe the problem originates in the tendency to rate open source projects using metrics like number of commits. A simple and elegant project that does not have recent activity is labeled as dead and people stop using it, even if it works well.
> Some React components have an invariant: “Invariant Violation: onlyChild must be passed a children with exactly one child”. Which means this is an error:
I'm surprise the author called this out as a negative of React while saying the compile time type safety is a positive of Elm.
If I have something that expects one child, I expect one child, not an array that has 1 element.
However, let's say later down the line a new engineer comes in and is tasked with a bug fix. If they're using Cycle.js and see an array, they might think, "Oh, I can easily solve this by adding another element to this one-element array." Without any invariants they'll run into subtler bugs and errors trying to figure out what went wrong.
But with the invariant, if they tried to jam an array there they would immediately get an error and know what's wrong.
This isn't something that will crop up in a simple one-day project like the author was creating with his coworker. It's instead a great example of how a little annoyance can make future maintainability way easier.
This part confused me: > I can confirm React/Redux is an inferior paradigm...
But all the examples don't show a "different paradigm", let alone a superior one. To me, they show the same paradigm, done better? The conclusion seems to support that interpretation as well.
Especially since he talks a lot about how much he loves Elm, and Redux went out of their way to copy Elm. The Elm/Redux distinction is basically syntax.
I never used Elm and a only dabbled with React a while ago but I remember having a very confusing feeling about React. When I read the introduction and basic ideas everything "clicked" and sounded obviously correct but when I went ahead to try to use it the library was much larger and complex than I would have expected. I suspect that the sizeable complexity might have to do with supporting stateful subcomponents that can be redrawn independently (as opposed to a system with a single tree that gets redrawn every time) or with their promise to support server-side HTML generation. Does anyone know if this is actually the case? How does Elm compare? Does it also allow stateful subcomponents?
Has there been any efforts to make use of js-csp [2] to handle async operations in Redux, like how ClojureScript apps make use of core.async channels?
Cycle.js definitely looks promising, but I have a vague suspicion that its approach of handling effects strictly through the output of the main function, although elegant, might make interop with the rest of the JS ecosystem a lot more painful, since many JS libraries don't have such clean separation of concerns. I believe JS interop is also one of the most commonly cited pain points for working with Elm as well, which uses a similar approach.
[1] https://twitter.com/dan_abramov/status/689639582120415232
My problem was the way in which the author got to this conclusion. Addressing React as "inferior" made the article feel like an attack on React when I think the author was really just trying to point out there are better ways to do things.
Of course React can do things better. Like I said, nothing is ever perfect and we are always building on the mistakes and learnings of the past. However, there are good reasons why so many people use it and it is an awesome option compared to some of the things we have used and done in the past. Eventually something will come along and do things better, but thats just the way the world works.
You will also meet people who believe the entire universe is made out of apples and oranges and that comparing the two is pointless. These people will never realize that there are things in the universe that are inherently superior to other things.
So which is the brick and which is the toothpick? React or cycle or elm? Or am I looking at apples and oranges? Ask the man who has built skyscrapers out of all three.
Will such a man please stand up?
Ack, I really do not like this. Detecting the meaning of each parameter based on its type is too much magic for me. If you're using positional parameters, they should be positional parameters. Otherwise I'm always having to guess how much magic is actually supported, and what each function call actually means.
both of these seem like an extremely long time to do something fairly simple in the native language for minimal gains and often huge tradeoffs (performance, memory usage, lackluster apis, etc)
This is generic, of course, and the article gives no real view of the capabilities of cycle as its own thing, but I feel sufficiently experienced to be skeptical of claims of blanket inferiority.
They don't get much hype but to me it's just a very mature and feature complete library with many "plugin" points to plug your own custom behaviour when you need to.
I did use React and I do find it unnecessarily confusing. In terms of performance gains, it doesn't really do a whole lot (for me). You still have to put a lot of though into structuring your rendering pipeline for maximum performance, and at the end of the day whether you spit out the DOM using react's "Virtual DOM" or some other custom templating engine doesn't seem to really make much of a difference.
React gets negative points for creating a parallel DOM structure and taking complete control of the portion of the DOM tree where it renders its components.