Redux Is Awesome

Redux Is Awesome

In my new role I've been given the opportunity to really dig into React, learn a lot about it, and build an application with it. I had previously used Ngrx in Angular 2 so it was interesting to go back to the original Redux library after having used the Angular step-cousin. After a few small roadblocks the application is progressing rather smoothly, and I have to say I think Redux is pretty dang awesome.


The Original Problem

Before modern front-end frameworks like Angular and React, you had to first get the local state in order and then write a bunch of code updating the view to reflect those changes. Those days are gone now as we have data-binding galore, and we can basically just put our JavaScript variables right in our templates. Huzzah! However, front-end frameworks also brought with them the double-edged sword of component-based architecture. The idea of breaking your app down into individual components seems like a good idea since it follows in the spirit of object-oriented values such as encapsulation, one responsibility principle, reusable pieces, don't repeat yourself, etc. I think part of what AngularJS got wrong (at least until 1.5) was not binding the HTML and the ng-controller tightly enough, into some logical unit that we like to refer to as component. Anyway, I do believe that building up an application from many small, focused components is a good idea. However, it does increase the complexity of managing the data in your application. It just does. When you have one huge component for your whole application you can just have a private variable at the component level which all of your functions can access, ie you just put everything in that component's local state. Easy boy. But, now you start breaking down your app into separate modular bits that can't access variables outside of their own enclosed scope. So, what do you do? When interviewing candidates, my team and I like to ask, "when is a good time to introduce Redux?". To me, the right answer to this question is, "as soon a you need to display the same data in two independent components". Sure, you don't need Redux for some proof-of-concept spike project meant to test some library, but imo any serious front-end project that you are planning to send to production one day should use Redux. But let's stop talking about Redux for a second and consider an alternative way to manage application state.


The "Mutable State Pattern"

Once upon a time I was building an AngularJs application basically alone for a client, and all of the sudden I needed to share data between two totally independent components (it what actually back when we called them controllers, but for this story I'm just going to call them components as it relates better to us today). I created an AngularJS service (which for other frameworks could really be any singleton class, one which always returns the same instance). I called it "DataHolderService", and it just held one huge object of other objects that eventually contained all of the strings and numbers, ie data, that was to be presented in the app. It got the job done actually. I would inject that service into the two components, and they could both reference the same object. I used this for a while and thought I was really clever for managing my state like this. However, in an argument against redux I was defendeding the mutable state pattern, but then my opponent presented me with this: 

"When you use your mutable state pattern, when any of the properties of your state change, you don't know what changed it."

I spent a lot of time trying to think of how to disprove this statement. With my front-end frameworks I no longer needed to manually update the screen, and when one component updated the state it would render an update for other components also using that service's data. However, I got to points where the components would be rendering something weird, and I would see the state object (via console logs) with strange data in it. But then what do you do? I mean, you basically have to just backtrack through your console.log statements and try to figure out what happened. Race conditions and async stuff can make things hairy. It is for this reason that I deem the "mutable state pattern" and anti-pattern that should hardly ever be used irl. Instead, I recommend Redux. **ahhhh choir of angel begins singing because someone mentioned Redux**


The Redux Solution

Redux basically allows you extract all your data into some object (aka the store) in its own file, and for all of your [smart] components you can say, "yeah, just update your display whenever that object over there changes any of these specific properties". The component then dispatches actions (which are defined by a string, normally named type, and an object, normally called the payload). This actions are handled by one of more reducers. A reducer is usually a file one function, reduce. Reduce takes two things as inputs: the current state and your action payload that you sent in. Inside of that function is usually just one big switch statement when you switch on the type for the action you passed in. So your case statements are just the strings that give a name to the different actions being fired. And here's the kicker- each of those case statements return a new state. It's important that they don't modify the state directly because then we go back to having the same problems as in the mutable state pattern. Instead. We create a new state and return it so that we have a history, a record book that we can look back on. We can say, "Ok. The state was first this, then I did this action with these parameters, and afterwards the state became this". You can follow it back to where that action was called, and with the Redux Devtools Chrome Extension you have an amazing visualization for analyzing this history of states and actions.


Going Meta For A Second

I really believe that every application is just a reflection of data that can be represented by a bunch of strings and numbers inside of nested objects. This is why Redux's one state paradigm makes sense to me. Different components many care about different "slices" of your state, but in the end it's all part of the whole application state. I like Redux better than the Flux implementation called Flux (for the reason above, and also just because I think it's a terrible choice for a name). And if you are one of those hipsters trying to push something lightweight thing like MobX, just go home. Redux is what is needs to be and nothing more. It's a way to represent the application state and manage it as it changes. So whether you are using Angular, React, or something else, I hope you will recognize that power and elegance of Redux that that it fills your front-end development days with organization, control, and joy.


要查看或添加评论,请登录

Jim Lynch的更多文章

社区洞察

其他会员也浏览了