It's really disappointing to me to see Redux being the "defacto standard" for React applications. It's overly decoupled for simple applications, which makes it harder to reason about the application. It also doesn't help that the Redux codebase itself is hard to understand.
It is only a tool you should reach for after you find you need it. Too few developers approach software development with this level of pragmatism and instead we get "use X because it's being used". I guess you need to understand the tool to know when to use it - but that doesn't mean it should become the "defacto standard".
Ironically Redux is being coupled with React, which is a great library for structuring UI into components and resulting it simpler to understand code.
While I understand your point, that's not entirely true; Redux itself is just a state management library, and thus _completely_ decoupled from React. You can use it with any other library/framework. In order for Redux to work with React, you need the _connector_ library, "react-redux".
Furthermore, Redux itself is a relatively small library, written in a heavily functional style. True, this may be hard to wrap one's head around for developers new to this, but I can think of no better place to learn due to not only the small size, but a lot of documentation and _very_ active involvement (in GH issues and StackOverflow) by it's author.
Not counting other parts of its API like combineReducers and subscribing listeners, Redux is essentially..
function createStore(reducer, initialState) {
let state = initialState;
return {
dispatch(action) {
state = reducer(state, action);
},
getState() {
return state;
}
}
}
It's quite simple.. and yes, it should only be used when needed, but the whole implementation of the Redux part of an app can exist in a few lines in a single file.
I'm a little confused by what you're trying to say, so help me out here. You say "it's overly decoupled for simple applications" and then "it is only a tool you should reach for after you find you need it." This would imply that you view Redux as a tool that primarily helps maintain larger React applications -- does that mean you think it doesn't make sense as the defacto standard as compared to, say, Flux? Or that there shouldn't be a defacto standard, or that neither of these is a good enough defacto standard?
Namely, I see Redux offering a nice advantage over flux in encouraging reducer composition (and functional purity) for modularity. "This pattern also enables wonderful features like no-user-code undo/redo. Can you imagine plugging Undo/Redo into a Flux app being two lines of code? Hardly. With Redux, it is—again, thanks to reducer composition pattern. I need to highlight there's nothing new about it—this is the pattern pioneered and described in detail in Elm Architecture which was itself influenced by Flux."
In short, the key value add for Redux, is not necessarily that it's (overly/inadequately) decoupled, but that it is necessarily forcing a decoupling via functional purity for the /purpose/ of modularity. That is, it is taking a more functional approach to state management for React components, favoring the event log paradigm rather than black box paradigm. This brings with it the ability to be "designed with use cases such as logging, support for Promises, Observables, routing, immutability dev checks, persistence, etc, in mind." Of course, these aren't impossible with Flux, but these things follow intrinsically from Redux.
Take my opinion with a grain of salt because I'm not super experienced with Redux yet, but I really like what I've seen so far playing with it.
It will take a person a couple of days to "grok" Redux, and a quite a bit longer to fully understand the ins and outs so one can make informed, confident decisions on how to solve problems "the Redux way".
Now you gain "cool" things by doing it, but here is the catch: Is the benefit worth the time investment to get there?
His argument is that for a lot of simple apps it isn't. You get very far with plain React, and a project has to have significant complexity to pay back the costs of fully understanding Redux.
I would argue a lot of people picking the React ecosystem make the mistake of choosing too much architectural complexity, not too little.
The extreme pluggability helps to broaden usage of Redux. But it is overkill for many projects. Decoupling is important, but it is not free (see parts of the Java ecosystem).
Devs should consciously decide what to introduce, and leave out stuff that simply doesn't increase development efficiency given the nature of their project.
Another commenter added the sentence I wish I had put in the original post. What I meant to say was, start with mostly pure components and just hold state in some top-level react components. Don't use react or flux. React makes it easy to share state between parent and child using props and callback registration which is perfectly fine to start.
When you find it hard to understand your state management within some parent react containers, or you're sharing a lot of state between siblings, consider flux or redux. Not before.
MobX is a nice alternative paradigm to Redux that is gaining traction in the React community. It allows you to declare your data as observable, so that components can update automatically to changes.
Wow what an absolute nightmare to wrap my head around. Reminds me of J2EE days of abstract patterns everywhere just because we can. Talk about simplicity.
The author addresses this point early on: "... earlier frameworks made building Todo apps simple but real apps hard. But React Redux make building Todo apps hard but real productions apps simple."
I don't think the author advocates using react-redux for the simplest todo list app.
I think the funniest part is that the total number of meaningful lines in Redux source code is less than 250. Compare that to the supplied documentation with over 6,000 lines of Markdown.
If you have any FP background, this is really nothing innovative, more of a common sense kind of thing. With the main achievement being that it's trivial enough and has nice documentation with examples so that mass JS programmers can actually grok it...
I've nothing against Redux, it's a good idea but quite a bit overhyped is all.
Has anybody tried both Redux and Baobab? If so, do you think Redux is better and why? I'm using Baobab in a couple of projects and really liking it, but Redux from the tutorial I read seems to a bit too general to me. In Baobab you can subscribe components to their particular branches and only those components will re-render if the branches change.
In Redux, it seems to me, there's no way you can do it, or at least nothing is provided out of the box. Am i correct?
You can use reselect in combination with react-redux for a similar effect. Reselect declares a view of the state, and react-redux manages connecting the component to this view.
I would say redux differs from baobab in not enforcing a state structure that mirrors the component tree. So it might be that if your state structure matches the component tree baobab is the simpler way, and redux is better if you need to decouple them.
I'm using redux with a structure nothing like the component tree. I ended up keeping updates and the tree trivial and keep all logic related to how to present the data in selectors (Reselect). Ending up with a structure not unlike the reflux implementation i was migrating from ;) to isolate parts of the state i have all subtrees export getters and actions so that reselect selectors works with the root getter for the subtree.
componentDidMount() {
item = store.getState().get('item') // Get function from Immutable.js
this.unsubscribe = store.subscribe(() => {
let nowItem = store.getState().get('item');
if (item !== nowItem) {
this.forceUpdate();
item = nowItem;
}
});
}
Someone may have a better solution, but I think this works fine for my needs. The internet is full of people dissuading redux users from subscribing to actions.
Nope. Redux does require that your reducers update their state immutably, but does not care HOW you do so. You can do it with Object.assign() / _.extend(), array slicing, the object spread operator, Immutable.js, the React Immutability Helpers, or one of the umpteen libs that provide abstractions for immutable updates like dot-prop-immutable or object-immutable-path.