Second Guessing Redux Implemetations
Most of you, are probably still pretty hyped about Redux, and don't get me wrong, I love that package and I think it changed JS scene in a great way. However for those of you, who're never fully satisfied, willing to further research alternatives, I'd like to elaborate for a second about the things that could be better.
Also I'll try to suggest possible ways out of the problems introduced. But don't take it too seriously, make your opinion and share it in comments.
Isn't it unfortunate to have one logic split between component methods and actions? Both of which are just one reaction to user's interaction. You may argue, it is a good pattern to separate concerns. I agree, but why like this?
We should recognise a difference between “state” related logic and “view” related logic, but the way we do it just adds boilerplate and sometimes it doesn't even make sense having several functions for one event. We have to pass it via arguments (I wont lie, I have some undefineds emerging time to time) of action creators. Like it isn't enough we have to juggle around the dispatch function, that's one more thing to worry about.
My point is, it may be an overkill boilerplate for one little onClick :-)
In my team, we like pure components much more than those “classy” ones. We create Higher Order Components in order to encapsulate some logic, so our render functions can be as simple as possible. This I see as a good pattern, so why don't we push it little bit further?
Imagine for a second you'd have 2 kinds of components. One only for logic (actions + handlers) and second one only for JSX (pure function style). The reusability would be actually better and the “shouldComponentUpdate” would be nicely handled by the “logic component”. Testability would be better, as you could test “view” and “logic” separately.
Let's focus on react-redux's connect function for a second. This part I don't enjoy very much, because it is hard to test, lacks memoization (by default at least e.g. reselect package) and it feels like bruteforcing some data into the component tree, without asking first. Also it often is the case, that the data from store “arrives” into our component little bit later than other props, resulting in us, forced to write statements like…
const rating = this.props.user && this.props.user.message && this.props.user.message.rating;
Consider for a second, that “connect” function would be part of the Logic Component's prototype.. therefore it'd be just like lifecycle method, which could be overwritten. Data connected via this function into the component, wouldn't be merged into other props, but stored in for example this.data or something. It would make above code example easier to deal with, less console.logs needed. It'd also more natural to “getState” based on data that is present in the component.
There we can go pretty far if we want, and make every single Logic Component method action, so every function is a thing state can react to and we wouldn't care about the dispatch, as it would be there by default. On top, it'd be much easier to test components, not wrapped like crazy, but separated by “What it does” not by “How it works”.
All I wanted to express with this post is that we shouldn't get stuck on this cool Redux thing. Let's make it even better, kill the boilerplate, introduce new patterns and live forever.