
Idiomatic Redux: Implementation and Intent - myth_drannon
http://blog.isquaredsoftware.com/2017/05/idiomatic-redux-tao-of-redux-part-1/
======
acemarke
Whenever a Redux thread pops up, there's inevitably complaints about
"boilerplate". I'd like to pre-empt those complaints a bit by pointing out
that, per part 2 of my post, it's entirely up to you how much abstraction you
use in your own Redux app. If you want use Redux for a particular use case,
someone has probably already written an addon or utility to help solve that
problem, and I've got them listed in my Redux addons catalog [0].

If you don't want to edit multiple files, use the "ducks" pattern to put
actions and reducers in a single file [1]. If you don't like writing action
constants by hand, use one of the dozens of action/reducer generation
utilities out there [2] [3]. If you don't want to manage normalized data by
hand, there's many addon libraries to help with that [4]. I specifically show
off one of them, Redux-ORM [5], in my "Practical Redux" tutorial series [6].

I love all the tools and addons that people are building on top of Redux. One
of my favorite quotes is from a Redux issue thread:

> Redux is a generic framework that provides a balance of just enough
> structure and just enough flexibility. As such, it provides a platform for
> developers to build customized state management for their use-cases, while
> being able to reuse things like the graphical debugger or middleware.

A few months ago I opened up a Redux issue thread to discuss further ways that
we could help make it easier for people to use Redux, and solve complaints
about "boilerplate". The discussion kind of trailed off, but I would love to
have more discussion and ideas for building useful new tools on top of and
around Redux to help people solve problems and build useful applications.
Please join the discussion here:
[https://github.com/reactjs/redux/issues/2295](https://github.com/reactjs/redux/issues/2295)

[0] [https://github.com/markerikson/redux-ecosystem-
links](https://github.com/markerikson/redux-ecosystem-links)

[1] [https://github.com/erikras/ducks-modular-
redux](https://github.com/erikras/ducks-modular-redux)

[2] [https://github.com/markerikson/redux-ecosystem-
links/blob/ma...](https://github.com/markerikson/redux-ecosystem-
links/blob/master/action-reducer-generators.md)

[3] [https://github.com/markerikson/redux-ecosystem-
links/blob/ma...](https://github.com/markerikson/redux-ecosystem-
links/blob/master/reducers.md)

[4] [https://github.com/markerikson/redux-ecosystem-
links/blob/ma...](https://github.com/markerikson/redux-ecosystem-
links/blob/master/entity-collection-management.md)

[5] [https://github.com/tommikaikkonen/redux-
orm](https://github.com/tommikaikkonen/redux-orm)

[6] [http://blog.isquaredsoftware.com/series/practical-
redux](http://blog.isquaredsoftware.com/series/practical-redux)

~~~
hesarenu
Mobx is an alternative. Simple and less boilerplate.

~~~
te_chris
This comment is always the first, every time, but they're both very different.
Mobx is mutable binding, redux is one way, functional data flow. They have
their tradeoffs, but when I look at mobx I get reminded of managing crazy
state trees in ember and why I went to react/redux in the first place. YMMV.

~~~
hesarenu
The crazy state tree in redux is what made me go to mobx. I had events firing
off updating multiple redux functions. It was very difficult to understand the
flow. Mobx has simplified my changes to one place. To me they both the same
managing client side state.

~~~
CuriousSkeptic
Mobx vs redux is probably not the right comparison here though. Mobx comes
bundled with 'computed' and encourages most state to be handled there.

Redux doesn't have this, instead libs like reselect fills space.

My experience with redux was frustrating in the way you explained, but once I
"got" how to defer all state to reselect instead of trying to do things with
reducers it got significantly simpler.

~~~
hesarenu
My frustration wrt redux was organising the file structure where to place
actions reducers. Otherwise it was a joy to work with. I considered it very
simple and easy to work until I found mobx.

~~~
acemarke
The two typical approaches are "file-type-first" (separate folders for
"actions", "reducers", "containers", etc), and "feature-first". I've got
articles discussing various React/Redux project structure approaches at
[https://github.com/markerikson/react-redux-
links/blob/master...](https://github.com/markerikson/react-redux-
links/blob/master/project-structure.md) .

~~~
hesarenu
I have done both approaches, ducks, slight variation on ducks all running on
production apps. Still not satisfied.

I have referred your links. Thank you btw.

------
acemarke
Hey, that's my post! :) Actually submitted this to HN previously, but didn't
get any traction. Ah, the fickleness of upvotes :)

Spent a lot of time researching for this post. What I really _wanted_ to write
was the second half of Part 2 [0], where I gave my opinions on why certain
usages are good ideas or bad ideas, but I realized I needed to cover a lot of
background before I got there :) Was really cool reading through the original
discussions and seeing the vision Dan and Andrew had for Redux from the
beginning.

Hopefully this pair of posts helps clarify a lot of the discussion around
Redux and its common usage patterns. Also, I'm always happy to answer
questions about Redux (and React) usage, and encourage people to come by the
Reactiflux chat channels on Discord [1]. Always a great place to learn and ask
questions about React, Redux, and related technologies. Finally, if anyone is
interested in learning React or Redux, I keep a big list of links to high-
quality tutorials and articles on React, Redux, and related topics, at [2].
Specifically intended to be a great starting point for anyone trying to learn
the ecosystem, as well as a solid source of good info on more advanced topics.

[0] [http://blog.isquaredsoftware.com/2017/05/idiomatic-redux-
tao...](http://blog.isquaredsoftware.com/2017/05/idiomatic-redux-tao-of-redux-
part-2/)

[1] [https://www.reactiflux.com](https://www.reactiflux.com)

[2] [https://github.com/markerikson/react-redux-
links](https://github.com/markerikson/react-redux-links)

~~~
rwieruch
Congrats Mark! :)

------
forgottenacc57
This article serves only to reinforce that the beautiful simplicity of react
is spoilt by the confusion of Redux.

I feel that every Redux blog post should start by pointing out that despite
react/Redux almost being discusssed synonymously, as the author of Redux
points out, "you might not need Redux".

I would go further and say "avoid Redux until you know you need it", and point
people to more simple ways of reaching the same goals.

Redux is a power tool for experts that is disheartening beginners and sending
them down the wrong path.

I was speaking to someone recently who had tried Reactjs. I wanted to enthuse
with him about how awesome it is. He said it was too hard and he went with
vuejs instead. When I questioned him further it became apparent that he had
started to learn react/Redux and gave up in confusion.

~~~
ChicagoBoy11
>Redux is a power tool for experts that is disheartening beginners and sending
them down the wrong path.

I've seen this expressed many, many times, and it is something that I've
honestly never quite understood. I started with React less than a year ago,
and it wasn't until I added Redux to my stack that I began to feel perfectly
comfortable with,

To me, the fact that actions dispatched in whatever component would cause the
global state to be recomputed which then got handed to react to render it just
a no-brainer. This truly makes data in React flow just one direction. The
tooling around it -- Redux DevTools -- also made seeing my app in action and
debugging it so incredibly clear.

Without it, for me initially it was a struggle about where exactly to store
certain state, and passing props and callbacks up and down all over the place.
It wasn't clean or easy to reason about at all.

As someone who had very limited experience in the framework, Redux felt like a
tool which made the pit of success for me pretty darn large. I do know that
even Dan himself has suggested that people not learn them in conjunction, but
to me, the coupling of them is so perfect that React only became a joy to use
WHEN I introduced it.

~~~
hacker-gene
> I've seen this expressed many, many times, and it is something that I've
> honestly never quite understood.

Well, if you're coming in from a non-FP background, learning Redux is
intimidating. I'm a aspiring web developer (I'm coming from tech support role
and my programming skill is mostly bash and bit of Python) and started looking
into Redux, and yay struggled with getting started.

    
    
      const store = createStore(reducer)
    

Took me hundreds of console.log ('entering func blah blah') before I realize
out that those reducers become properties of the object store. So yes, Redux
is power tool for expert and not as nearly accessible to your average
neighborhood web developer.

~~~
acemarke
I'd be very happy to discuss any pain points or particular problems you've run
into trying to learn Redux, and any suggestions you might have for improving
the docs to make it easier for others in the future. Please feel free to ping
me on Twitter, or in the Reactiflux chat channels.

------
Jare
The article does a great job of presenting Redux and stripping the "magic" out
of it. But the section about dependencies between reducers bugs me A LOT.

"If a CommentsStore needed data from a PostsStore to properly update itself,
it could call PostsStore.waitFor() to ensure that it would run after the
PostsStore updated. [...] with Redux, that sequencing can simply be
accomplished by explicitly calling specific reducer functions in sequence."

And it introduces a specific call order of slice reducers, and
'hasCommentReallyBeenAdded' variable, inside the root reducer to implement
that dependency.

But it looks to me like such a dependency will usually be specific to a
certain action, and in a modestly complex application, different actions will
have dependencies in different orders, with different ordering and information
needs, and moving those into the root reducer doesn't scale beyond one (i.e.
the shown example). Thus, as is, the section doesn't really provide a useful
pattern for building real apps. Those will need a different approach -
represented by the catch-all but not so useful "it's all about how you want to
write it."

Am I missing something about that section and topic?

~~~
acemarke
Missing a bit, yeah.

It's entirely possible that the `commentsReducer` does know how to handle all
relevant actions. It's also possible that it only needs that extra data for
one specific action.

One of the biggest advantages of the "reducer" concept is that _they're just
functions_, and you can mix, match, and combine them in any way that works for
you. I show several examples of additional custom reducer structures in the
"Structuring Reducers - beyond `combineReducers`" [0] section of the Redux
docs, and also in my blog post "Practical Redux, Part 7: Feature Reducers"
[1].

As a quick summary, instead of having the `combineReducers`-generated function
as your root reducer, you can further wrap that up in other functions, such as
one that takes an array of reducers and runs them in sequence, or one that
only does that special handling for a specific action case and otherwise
delegates all handling to the normal `combineReducers` approach.

[0]
[http://redux.js.org/docs/recipes/reducers/BeyondCombineReduc...](http://redux.js.org/docs/recipes/reducers/BeyondCombineReducers.html)

[1] [http://blog.isquaredsoftware.com/2017/01/practical-redux-
par...](http://blog.isquaredsoftware.com/2017/01/practical-redux-part-7-forms-
editing-reducers/)

------
toprerules
When I first came to React my understanding was that React/Flux were all but a
package deal, and that I better use Redux because it seemed so popular. Redux
quickly became a pain point in terms of boilerplate and added cognitive load.
Now a top level stateful component works for 90% of my use cases.I feel the
same way about React Router. Maybe if you're building something quite large or
complex these prepackaged tools make sense, but I personally have gone the way
of Golang and started to prefer a little copying over adding an extra
dependency and I've found that React is wonderful by itself. I encourage
anyone who will listen to try ditching Redux in favor of a single top level
stateful component.

~~~
learc83
I wouldn't recommend this at all. Sure if you have a tiny site with very
limited functionality or you're learning react, you don't need redux.

But if you're using components they way they're intended, (not cramming
everything into a few overloaded components), you're quickly going to be
passing down props down through layers and layers. It will quickly become a
maintenance nightmare.

Just imagine that you have a button component that is 5 or layers down from
you're stateful component. It's getting props to control it's state passed
down through all 5 levels, and it's getting functions to change the stateful
component's state passed down through all 5 levels. Now what happens when you
want to move the button from your side bar to your footer?

Redux solves a very real problem, there are other solutions to this same
problem, but eventually any non-trivial app is going to need something for
state management beyond a single top level stateful component.

~~~
ilovecaching
I actually find it easier to reason about my components when I can trace data
sharing in my hierarchy rather than allowing components to cheat and
circumvent sharing state in their common ancestor. I think it's idiomatic
React to construct hierarchies of functional components topped by very few
stateful components. Using connect() to turns components deep in the hierarchy
into stateful components can only lead to a less declarative dataflow that
tightly couples those components to Redux for very little gain.

If you're having difficulty moving components around because of state consider
that you may be thinking too statefully and should try to find a less stateful
way to describe your UI, or that the UI you have constructed does not
adequately group related pieces of data and functionality together, which will
lead to a confusing UX.

~~~
qudat
I get what you're saying but for large react applications using Redux helps to
dramatically reduce state complexity and increase maintainability.

Having one function 5 levels deep that receives its props from a top level
function means everytime you add a prop you have to modify 5 function
signatures to get that new data. That quickly becomes unsustainable when you
have 10+ layers.

What happens when you want to modify the prop that is set in the parent? You
have to pass through a callback function that will modify that parent props
and then trigger a re-render.

Very quickly you end up with problems that flux/redux/mobx try to solve.

------
qudat
I use react/redux for a very large application and overall it has been a
powerful, robust, and scalable solution that handles 99% of our use-cases.

The biggest problem I struggle with is knowing when components rerender.
Libraries like reselect that memoize state-composed functions really help with
performance, but make it less clear when things are being rerendered and why
they are being rerendered.

I also agree with some of the posts here that handling async actions, or side
effects, can be rather difficult in the redux model. Redux-thunk is still
being recommended even though Dan created it more as a bandaid solution rather
than something more robust. We solved it with redux-saga, but my colleagues --
experienced developers -- struggled initially to grasp generators. I also
think sagas run into the same problem that one action triggering multiple
reducers has which is you could inadvertently trigger an action that hits one
or more sagas and not realize you are causing side effects that you did not
intent. I know there have been countless discussions on what to do about this
problem, but I fear the solution will always be outside of the scope of the
core library because of backwards-compat.

~~~
acemarke
I have links to a number of useful utilities for visualizing when and why
components re-rendered in the "DevTools#Component Update Monitoring" section
of my Redux addons catalog [0]. Hopefully those help.

I'm a bit curious why you say that "reselect makes it less clear when things
are being re-rendered". The overall reasons shouldn't change - connected
components will re-render when values from `mapState` or props from the parent
component have changed by reference.

Thunks are definitely the "minimum viable approach" for handling async logic
in Redux, or at least the minimum _suggested_ approach (as opposed to doing
async handling purely inside of a component). I agree that sagas (and
observables) are a pretty big jump for most devs to make, but then again,
async logic in general is more difficult to reason about. Personally, I still
think most devs should use thunks until they see a need for something else
(per my post "Idiomatic Redux: Thoughts on Thunks" [1]).

Redux does deliberately push the question of "how do I handle async logic?"
outside of its core, and leave it up to you. That's both because Redux focuses
on structuring synchronous state updates, and because (per my post) Dan and
Andrew wanted to give devs flexibility in what specific technique they use for
handling async.

[0] [https://github.com/markerikson/redux-ecosystem-
links/blob/ma...](https://github.com/markerikson/redux-ecosystem-
links/blob/master/devtools.md#component-update-monitoring)

[1] [http://blog.isquaredsoftware.com/2017/01/idiomatic-redux-
tho...](http://blog.isquaredsoftware.com/2017/01/idiomatic-redux-thoughts-on-
thunks-sagas-abstraction-and-reusability/)

------
saosebastiao
I'm infinitely more comfortable with functional composition over object
composition, but Mobx is still far more intuitive to me. It's because
functional composition over a constantly changing global state tree is a huge
fucking mess. There's a reasonably objective explanation as to why it is a
mess, and more specifically, why Redux suffers from so much boilerplate and
painful refactorings.

In UI programming you are managing state, full stop. Almost any UI can be
described as a state machine. Not just GUIs, but any UI: digital, analog,
mechanical, whatever. And since you are basically managing state machines, any
refactoring of the _functionality_ of your UI is fundamentally a refactoring
of your state. Rendering is a functional refactoring (state doesn't change),
but if you are building a UI and not just a simple landing page, you are far
more likely to refactor functionality over rendering...meaning your data is
more likely to change than your functions. In other words, _UI programming via
functional composition over a frequently changing global state tree falls on
the wrong side of the Expression Problem_ [0].

Every time you change your data, you have to modify every functional pipeline,
from beginning to end, that touches that changed section of your state tree.
That is where all the boilerplate comes from, and that is why Redux is
consistently criticized as a system that becomes more and more unwieldy as
your UI complexity grows. It is a bad abstraction for the problem at hand.

Mobx is a far better pattern IMO, and I feel entirely comfortable saying that
is an objective position to take as long as your functionality is more likely
to change than your rendering. It isn't that Mobx is a superior idea, it's
just the fact that it embraced object composition for a use case that is
perfect for it.

[0]
[http://wiki.c2.com/?ExpressionProblem](http://wiki.c2.com/?ExpressionProblem)

------
davedx
I've just started another side project using React with redux. One of my goals
is to keep my code as simple as possible while still being able to build a
large application.

To keep it simple, I'm not using react-redux (I often try to avoid this), and
I generally pass the entire store down through all child components, again to
keep it simple. My top level app with its simple navigation code subscribes to
the redux store and sets its state from it. My router is just a bunch of
statements like {pageName === 'connnections' && <ConnectionsPage {...props}}.

To avoid too much boilerplate, I find most of the time all you need are some
helper functions. I have a helper function called 'action' that I call like
action('LOAD_SOME_DATA') that dispatches on the store with type:
'LOAD_SOME_DATA'. I use a simple 'getIn' function to access nested data, and I
mutate data in my reducers with object-path-immutable. Everything is clean and
easy to read.

I believe one of the biggest problems with the React community is the constant
bleed of 'performance' into app design and development. Premature optimization
is everywhere.

Guess what, most apps won't need immutable data and free componentShouldUpdate
checks, memoized selectors, or subscribing to subsections of the store using
complicated 'connect'/high order component plumbing.

The one time I actually had a perf issue with React was when I had a GIGANTIC
list of data (showing all the active salespeople in our company -- we have a
lot), which due to me storing form state in redux was being completely re-
rendered every keystroke.

The solution wasn't to add react-redux or start using immutable data - it was
to add paging and filtering. I improved performance, but more importantly, the
UX of the app with this.

If your React app really is so huge and complex that it needs reselect, react-
redux, react-router, great stuff -- you are obviously building software for a
successful product with lots of feature requirements. Most apps I've worked on
never got to this level of complexity.

~~~
acemarke
I'm _very_ curious: why do you feel you need to "avoid" React-Redux?

There was a similar thread on Reddit a few days ago, asking why the OP should
bother using React-Redux [0]. I'll paste the main part of my reply:

> First, while you can manually write the code to subscribe to the Redux store
> in your React components, there's absolutely no reason to write that code
> yourself. The wrapper components generated by React-Redux's connect function
> already have that store subscription logic taken care of for you.

> Second, connect does a lot of work to ensure that your actual components
> only re-render when they actually need to. That includes lots of memoization
> work, and comparisons against the props from the parent component and the
> values returned by your mapStateToProps function for that component. By not
> using connect, you're giving up all those performance improvements, and your
> components will be unnecessarily re-rendering all the time.

> Third, by only connecting your top-level component, you are also causing the
> rest of your app to re-render unnecessarily. The best performance pattern is
> to connect lots of components in your app, with each connected component
> only extracting the pieces of data it actually needs via mapStateToProps.
> That way, if any other data changes, that component won't re-render.

> Fourth, you're manually importing the store into your components, and
> directly coupling them together, thus making it harder to test the
> components. I personally try to keep my components "unaware" of Redux. They
> never reference props.dispatch, but rather call pre-bound action creators
> like this.props.someFunction(). The component doesn't "know" that it's a
> Redux action creator - that function could be a callback from a parent
> component, a bound-up Redux action creator, or a mock function in a test,
> thus making the component more reusable and testable.

> And finally, the vast majority of apps built using React and Redux use the
> React-Redux library. It's the official way to bind the two together, and
> doing anything else will just confuse other developers looking at your
> project.

> So, part of the issue is you're not using React-Redux and connect, and part
> of the issue is you're using an inefficient pattern for pulling data from
> the Redux store into your React components.

So no, many apps don't need to spend tons of time optimizing performance, but
at least part of that is because `connect` already handles a lot of that for
them. There's also other reasons for immutability, per my original post for
this thread: time travel debugging, testability, and ability to reason about
state updates.

Also, in regards to the "re-rendering on every keystroke" issue, my post
"Practical Redux Part 7: Form Change Handling" [1] shows off a React component
I made that specifically helps buffer those for fast form updates, while
debouncing the number of Redux actions dispatched.

[0]
[https://www.reddit.com/r/javascript/comments/6hperk/i_use_re...](https://www.reddit.com/r/javascript/comments/6hperk/i_use_react_and_redux_but_never_reactredux_what/)

[1] [http://blog.isquaredsoftware.com/2017/01/practical-redux-
par...](http://blog.isquaredsoftware.com/2017/01/practical-redux-part-7-forms-
editing-reducers/)

~~~
davedx
Because of the extra complexity and cognitive overhead introduced by connect.
It obscures the one-way dataflow in React in a similar way using 'context'
does, making it less explicit. There are benefits, but I like being able to
trace the flow of state through my app in the code.

Second and third points both concern performance. See my OP: it's a premature
optimization. How many people honestly run into rendering performance issues
when building a single page app? Why introduce extra complexity for
performance you don't need?

Fourth point: no, I don't manually import the store into my components. My top
level app component subscribes to the store (3-4 lines of code), and passes
the data in the store down into its child components, including my routing
component and all the rest. Most of them are dumb stateless functions that
just render from their props and call the occasional action function.

Action functions themselves aren't on props and don't do any binding of any
kind. They are just functions that provide a simple abstraction on top of
store.dispatch. Again, simplicity.

Regarding confusing developers: I disagree with this statement 100%. We have
two React apps at work, one that uses the simple approach without react-redux,
and another that pulls in most of the usual ecosystem: react-redux, react-
router, redux-form, and so on. The cognitive overhead is larger; reasoning
about the code is harder; the greater number of libraries means we've had bugs
in those libraries that cause difficult to solve problems.

It's just an opinion of mine, but in my experience, React and redux by
themselves can get you a very long way before you _need_ to pull in other
libraries.

------
mg74
Just want to put down my flag in the sand and say I love Redux. It is my tool
of choice whenever dealing with anything that contains state and (with it's
partner in crime, Redux Saga) anything that has to do with the real world
(dreaded side-effects).

Thumbs up on Redux, your boilerplates are my sanctuaries.

------
softwarelimits
Hihi, I catch myself scanning through react posts just to find something about
vuejs :) - it seems to be kind of a 'natural social law' that 'the mainstream'
never is the real thing.

------
sAbakumoff
I don't event want to open the article that has both of "idiomatic" and "tao"
words in the title.

~~~
acemarke
For what it's worth, "Practical Redux" is my blog series that demonstrates
Redux techniques by building a sample app. "Idiomatic Redux" is my series for
my own thoughts on why I think certain Redux usage patterns are good or bad.
The phrase "Tao of Redux" was just something that popped into my head and
sounded catchy, and seemed to go along with the idea of "explaining the Redux
philosophy".

~~~
sAbakumoff
It sounds like the author is some kind of guru who became enlightened and
willing to share the "tao" of "idiomatic" way of JS library. Can't you see how
pretentious it it?

~~~
acemarke
Well, _I_ am the author, _and_ a Redux maintainer, _and_ I've spent a ton of
time discussing and using Redux :) I can legitimately say I'm _an_ expert on
Redux, its implementation, and its use.

The original point of writing it is that I see many people complaining about
things like "having to use action creators" and "having to edit many files",
when Redux itself doesn't actually require you to do those things.

So yes, I guess you could say that I _am_ trying to enlighten people, because
many of the complaints about Redux are being made out of an incomplete
understanding of why it exists and what its intended use is. If people still
don't like Redux after that, that's fine - I just want people to better
understand why Redux usage patterns exist and clear up the misunderstandings.

~~~
weq
The problem with redux is actually the dev-tools (and the ecosystem that
spawned from the middleware). the newbies get wowed by "time travel debugging"
and want to copy/paste there way to the $$$profit.

Redux takes a simple concept, and turned it into something thats really hard
to apply to the projects these people are writing; by reinventing words into a
propriety language.... No one talks about about there state as a function of
"reducers". And when they think they have their head around "actions" they
realise that no, its not a 1-to-1 relationship with what the user is doing.

If redux didnt try and re-invent event-sourcing with its own "idomatic TAO
way", it could of leveraged off the plethora of well written documentation on
the subject.

Instead, Dan, thought he could improve event sourcing and make it palatable
for the masses by -replacing "events" with "actions" [1] -making the state an
anemic domain model[0] -persisting snapshots instead of an event log then
adding on congnitive load by implementing a diffing algorithm for UI updates
which requires specialised knowledge. [1]

[0]
[https://martinfowler.com/bliki/AnemicDomainModel.html](https://martinfowler.com/bliki/AnemicDomainModel.html)

[1]
[https://martinfowler.com/eaaDev/EventSourcing.html](https://martinfowler.com/eaaDev/EventSourcing.html)

~~~
bradmwalker
Another red flag on redux: recommended practice--query JSON over HTTP (likely
backed by an RDBMS), renormalize the hierarchical data, and then reshape the
renormalized data before passing to components.

~~~
sAbakumoff
Right?! and redux is a baby-monster comparing to Relay that demands developer
to actually modify the server's graphQL API in order to comply with the odd
requirements.

------
nikolay
The React ecosystem is growing out of control! JavaScript was a revolt against
the overcomplicated Java ecosystem, but it is now worse than its original
enemy with favors, opinions, and best tools for the job changing daily!
Remember when JSON came out as an alternative to XML? Now all XML technologies
have JSON equivalents - schema, pointer, etc. What was the point of the switch
then - keep spinning wheels and not moving forward? With Babel being the
centerpiece of JavaScript development today, can we at least apologize to GWT?

