Check out a free preview of the full Intermediate React, v2 course:
The "Creating a Reducer" Lesson is part of the full, Intermediate React, v2 course featured in this preview video. Here's what you'd learn in this lesson:

Brian explains best practices for writing reducers, as well as requirements and philosophy behind them. The reducers directory is created with an index.js file, and combineReducers is imported as a convenience root reducer. Two reducers are created, and wired into the root reducer.

Get Unlimited Access Now

Transcript from the "Creating a Reducer" Lesson

[00:00:00]
>> Brian: We're gonna make a new file. Actually, let's just make a whole new directory instead of source. And it's gonna be called reducers., or just reducers, rather. Inside of reducers, we're gonna have one called index.js. This is gonna be the root reducer. So we're gonna say import. combineReducers, combineReducers from 'redux'.

[00:00:30] This is just a little helper method that makes writing the root reducer a little bit easier, and then we're gonna make another one called import location. The location reducer from ./location which we haven't made yet, but we'll make here in just a second. And I want to say export default combineReducers and give it an option of location: location.

[00:00:58]
>> Brian: But because these two are the same things, we can actually just combine them into one thing, right? So if I say that, we can actually just do that.
>> Brian: So what combineReducers does, you can think of a Redux store as a really big object, right? It's supposed to be a tree of data.

[00:01:20] So we're gonna keep track of our location here, do I still have. This one, right? We're gonna keep track of this location inside of Redux instead of being inside of React, right? So we're gonna make this location reducer only affect this location parameter or piece of the state tree.

[00:01:47] So we're saying any time that the location gets modified, run this reducer, basically. Does that make sense? Cool. So let's go make another file here called location.js, inside of this Reducer's's directory. And this is gonna be a really simple reducer, it's gonna be export default function location, you're gonna give it a default state.

[00:02:16] The state = and make it whatever you want, Seattle, Washington or San Francisco, California. And that's gonna take in an action as well. So if you've never seen this in a parameter before, it's saying, hey, if I get state, then use that, if I don't get any state then default state is this, right?

[00:02:36] Just makes that a little bit easier.
>> Brian: And then I'm just gonna say if (action.type === 'CHANGE_LOCATION') return action.payload.
>> Brian: Else return state.
>> Brian: Now, we can turn this into a switch statement as well. I think actually in my notes, I do it that way, but it's basically just an if statement.

[00:03:17]
>> Brian: So, what is action? Action is gonna be an object that I get from whatever is dispatching the action to redux. So I'm saying, hey, redux, only respond in this reducer if the action type equals CHANGE_LOCATION, right? Otherwise don't do anything, just pass the object on, right? So in this particular case, if I got an action type of CHANGE_ANIMAL, it would just ignore it, right?

[00:03:47] But in this particular case it's saying, if this is CHANGE_LOCATION, then I want you to update it to be whatever the payload is. If it's now San Francisco, California, then update it to be that. Does that make sense? Now, we have this function here, this reducer, and this is so testable, right?

[00:04:06] I can test this a million different ways. Okay, if the state is this, if the state is that, if the state is empty, if the state is null, if the state is numbers, right? And you can say, given this state and this action, I should always get this thing back, right?

[00:04:18] It's which is the computer science term that means I can run this 1,001 times with the same parameters, and on the 1,001st time, it's gonna work exactly the same way. Now, if I was doing something like this where I had let x = 0, and then I was saying x++ and + x, right?

[00:04:46] I didn't know this was, that's funny. It puts those together. This is a problem, right? This is no longer a pure function. This has side effects, this is no longer right? If I call this a 1001 times, on the 1002nd time what's it gonna be? Something different is the answer, right?

[00:05:04] It doesn't matter actually what it is. It's just not the same on the 1,002nd time. So don't do this. These should be pure functions that you can run them as many times as you want, and nothing ambient is changing about it.
>> Brian: It must have a default state, so make sure you do that.

[00:05:27] And the other thing here is if the action type is not the one that you're paying attention to make sure that you just return the state, right? Because it assumes that you're always going to return a state of some sort. That's a very key thing here. So if I didn't have this part and I had some action that I didn't recognize, right?

[00:05:48] So if this was CHANGE_ANIMAL, the new state would be undefined, right? Which is probably not what you want. Notice I'm using action.payload here, and action.type. The only thing that your action has to have is a type, that's hard requirement, must have a type, okay? What you call the payload is up to you.

[00:06:09] I'm choosing to adhere to something called a flux standard action.
>> Brian: There's no real reason I have to do this. It's just Andrew light, who's or Andrew ACD light. Clark Andrew, Clark is his name, works at Facebook and one of the co-creators of Redux. Made this and he just described that this is what actions should look like, types, payloads, error, and meta.

[00:06:39] That's the only thing that they can have, right. Everything else should just go into payload basically. You don't have to adhere to that. But I just don't have a better idea. So I just choose to adhere to it.
>> Brian: Okay, good. We're gonna make one more reducer for theme, I wanna say theme.js.

[00:07:09] We can actually just copy and paste this. It's gonna look almost the same. So this is gonna be darkblue for the initial state, and this is gonna be CHANGE_THEME, and the name of this function is going to be theme.
>> Brian: Now, I know you're probably sitting there thinking things like, could I make this into some, like, abstract reducer generator?

[00:07:34] You can, and there are libraries that will help you with that. But for now, let's just be explicit, right?
>> Brian: I'm of the fan, have you heard the term dry code, right? Do not repeat yourself. I'm very much a fan of wet code, write everything three times. And then after the fourth time, then rewrite it into some thing, right?

[00:07:57] Because premature optimization kills projects, right? How many times have you written something abstract, right? And then never use the abstract part of it and now it's just difficult to use, right? That frequently happens to me. I didn't make that up, by the way, someone else made that up.

[00:08:14] Okay, so I'm gonna say import theme from ./theme and theme here.