Check out a free preview of the full Enterprise Architecture Patterns course
The "Reducers" Lesson is part of the full, Enterprise Architecture Patterns course featured in this preview video. Here's what you'd learn in this lesson:
Lukas demonstrates how reducers are used to manage state changes. A series of conditions are checked with a case statement to determine which action's method should be called. String-based action names should be replaced with constant variables to reduce code duplication.
Transcript from the "Reducers" Lesson
[00:00:00]
>> So, we want to build a reducer function. And how this works is a reducer function outside of state but just in general, is that it takes some parameters. And then it reduces the whatever you send in it reduces it into its final state and then returns it.
[00:00:29]
And so when we use a reducer for state management, what we're saying is ,here is the state and then here's the action that we want. So interestingly enough, if we go back to this calculate this is kind of a similar situation, here we're saying, here's the two numbers available.
[00:00:49]
And then here's the operation. In this case, we're saying, here's state, and then here is your action, which has the type of action that it is plus the payload. But what this does is it accepts. It takes state and the action and then based on the action type, it calculates new state and then returns it.
[00:01:13]
And so we kind of hinted at this. In our refactoring example, this is an air traffic controller function. That its primary existence, the reason why it exists is to delegate. Now, if you've done NGR x or if you've done Redux and you're seeing complex logic in these nested statements.
[00:01:44]
That is bad, and I would say I've seen a lot of criticism for Redux and NGR x because of that. And again, that's not because Redux or NGR X is bad. It's because hidden state is bad and it has no, it's no commentary or indictment on the design pattern.
[00:02:05]
When you're essentially invalidating it with an anti pattern, so in this case, load, select, create, update, delete and clear. And an action in this case is it always will have a type and then it may have a payload. So this is where this question mark means is that maybe, you'll have this or maybe you're won't.
[00:02:29]
And then from here what I just wanna point out because the cats out of the bag, we know what we're building. Is that one thing I do recommend, is in your case statements, these are magic strings and you want to extract this out. And so what I will do at a minimum is extract this out into essentially const.
[00:02:55]
Higher level variables that I can reference that I then put in here so that I don't have these magic strings floating around. In my code, cuz that's a really bad way. Or rather, what happens if I needed to reference create somewhere else? Well now I've got code duplication.
[00:03:21]
And so again you just extract to a parameter. And so this is again, just elevating this. And so when you have strings, the primitive strings in your code, it makes it really hard to reuse those. So this is where you extract these out. And you turn these into these kind of constant variables.
[00:03:41]
Now you'll notice as well. That load, select, create, update, delete clear. The problem with that is outside of context or if you're unless you're looking at this code you don't really know. What that's actually talking about, but the only way that I know that we're talking about creating clients is because inside of that code, it says Create client.
[00:04:17]
And so I have to actually infer that meaning. And so the other thing about writing code is that it should be self documenting. You should be able to look at your code and immediately know what it does. So the difference is that, we're here we just have load, select, create, update and delete.
[00:04:38]
Well, what what are we doing? What are we talking about? There's no modifier there. Now over here case, client create. Without seeing the code, we have a pretty good idea what that is client delete. And so it's really important, even at the cost of verbosity, in other words, computers, we're not dealing with 256 k.
[00:05:06]
That's a K of RAM, where we actually have to manage our own memory and like our lion counts the characters in like this matters. Is that right code to be readable? This is why we have Webpack. This is why we have Bundlers like they take care of that like I've just seen code where it's so terse and so concise and so clever that it is just ineligible.
[00:05:37]
Like you can't even you have no idea what's happening, that if you've ever seen, like, minimize code, like I've met people like that's how they write code and it's completely opaque. What is actually happening? And so that's a little side bonus that didn't cost anything. But when you write code that is self documenting, more often than not, you do not need documentation in the form of comments in your code.
[00:06:07]
Comments are really in my opinion, it's typically relevant when you write it and then it goes stale almost immediately. And so you should avoid excessive comments and just write code that really makes that point for you. I am going to create a reducer and we'll just step into this and get started.
[00:06:33]
So, I'm gonna call this const, clients, reducer and this is a function. And. It takes two parameters. So it's gonna take, state, which is going to be client state. Work with me here. There we go. And it's going to take an action. And what I can also do is I can pre initialize this parameter to the initial client state.
[00:07:21]
Now from here, what I'll do is I'm going to make a switch case and I'm going to go action.type. Now, you'll notice here that when I go dot, nothing happens because we haven't defined what an action is. And so what I'll do is I'll just go interface action, and it's going to have a type which is a string.
[00:07:49]
And it's going to have a payload, which is optional, and this is gonna be any. So a payload just can really be anything and I'm gonna just copy this and I'm gonna move it up to the top. This is kind of a super top level thing. And now within the reducer, if I type this and so this is, again part of this as we start to turn this over and get our hands dirty.
[00:08:21]
You'll notice that now, when I type this parameter that it's now telling me. Or giving me some hints about what I can use and then from here cuz I already know what I'm going to do that I'm going to create. Some actions what I will do here just because this would take a bit of time and I don't know if it is exciting for you as it is for me to sit and watch me type.
[00:09:06]
So I'm just gonna copy this out of solutions. You can yell at me later, but this allows us to be a little bit faster. So all I've done is I've just copied these constant variables in here, and we'll go case and we'll go client, Load, And we're gonna do something.
[00:09:31]
And what I'll do is I'm gonna do just a couple of them. Maybe let's do, client select. And I'm just going to return load, clients, state, action. Now this doesn't exist, but it will eventually. Return select, client, state, action. And what I can actually do here is I can just send in the payload because we already know what the type is, hello I can actually even get rid of these braces here.
[00:10:40]
Make the super nice and tight And then what we're gonna do is if something does not match up, we're just going to return state, all right. Now, let's go ahead and just create placeholders for these methods, little clients. It's going to take state. And clients and then it's going to do something.
[00:11:13]
So I'm just going to log this out of clients Select client. This is going to take a client select client. There we go. So this is angry about shadow names. That's okay. We can live with that. There we go. And so the big thing here is that we are now creating a mechanism in which we can manipulate state based on a particular condition.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops