Designing simpler React components
medium.com
medium.com
I think it's interesting that Elm and ClojureScript have chosen immutability as the default. I wonder what other languages have chosen this.
you also have Haskell for immutability by default and with no other option :)
Also, there are options to use immutable for state with redux (it's a little different), but it can be useful, to say the least.
The only downside of static components is that hot module replacement doesn't seem to work right, there are ways around it, but not as much fun... that said, I tend to save state to sessionStorage on every change, loading from sessionStorage at start, so refreshing the browser will just show the updated rendering.
Also, I believe Chrome and Firefox (and hopefully other) garbage collectors use a generational algorithm which makes it very cheap to throw away short-lived objects.
Of course it's more efficient just to mutate state, but these factors and other optimizations should mitigate the added cost and I think for most applications, the wasted cycles are not going to be much concern.
http://swannodette.github.io/2013/12/17/the-future-of-javasc...
The standard "react-redux" bindings make use of the presentation/container component pattern described here as well.
Imho there's nothing special with async actions and you don't necessarily need an addon, they're just actions arriving to the reducer later, and it can't see the difference. Your data fetching is no more async than a user clicking on a button.
http://redux.js.org/docs/advanced/AsyncActions.html
Note however that it does say "This function doesn’t need to be pure; it is thus allowed to have side effects, including executing asynchronous API calls."
I have simple action creators that are simple actions, where the reducers only update state... actions creators will do anything more complex...
export const doSomethingAsync = input => async (dispatch, getState) => {
try {
dispatch(updateStatus('loading'));
var response = await client.get('...');
dispatch(updateStatus('success', response.data));
}catch(err){
dispatch(updateStatus('failure', err));
}
}
I prefer the redux-thunks with async functions, as this lets me be more explicit and do a bit more work, if I need more status levels than loading/success/failure modes. This is a relatively simple example, and pretty close to how the defaults for redux-promise works...There's no side-effects to having your async calls inside your action creators... Well, there's a chance that an intermediate action may be dispatched in between the loading and success, but even then, unless things are very brittle, it's easy enough to mitigate, and that's only for portions of the tree that are shared.
Just the same, the exposure is still minimal, and easily testable.