Check out a free preview of the full Complete Intro to React, v3 (feat. Redux, Router & Flow) course:
The "Setting up Redux" Lesson is part of the full, Complete Intro to React, v3 (feat. Redux, Router & Flow) course featured in this preview video. Here's what you'd learn in this lesson:

Brian creates a rootReducer object for the application and explains how the state will be passed to and returned from the reducer. Then Brian creates the store for the application. The createStore method in Redux is passed the rootReducer to create the store. Brian creates the actions for the application. While the files do not need to be in separate files, Brian stores the action definition in an actions.js file and the implementation of the action in an actionCreators.js file. Actions trigger the reducer to carry out the modification of state.

Get Unlimited Access Now

Transcript from the "Setting up Redux" Lesson

[00:00:00]
>> Brian Holt: First thing we're gonna do here is we're going to define our default state.
>> Brian Holt: So that's going to be equal to searchTerm.
>> Brian Holt: So, but we're gonna migrate first to Redux is we're gonna take the search term searching and we're going to migrate that into Redux. And then we're gonna make both landing and search read from our Redux store for it.

[00:00:25] So const rootReducer = (state = DEFAULT_STATE, action)
>> Brian Holt: Okay? And I guess the other thing is worth mentioning. I'm gonna show you how to do this without flow first because flow makes Redux better, in my opinion but again, it's more levels of complexity on top of it. So I wanna show you how to do it without first.

[00:01:01] So, switch (action.type) and default return state, and export default rootReducer. So let's talk about what we did here first. At the top level of every store is one reducer, right, in that case it's the rootReducer. And again, when I say reducer it takes in state, it's takes it in action and a returned state.

[00:01:37] That is what a rootReducer does. It has no side effects to borrow from our functional friends and their terminologies. That means that I can call this 10 billion times with the same state and the same action and I'm always gonna get the same state out of it, right?

[00:01:52] So you don't want anything happening around it. You don't want it to have like a counter here and say like counter++, right? Cuz that would be a side effect, right? That means if I call it 10 billion times, I'm gonna get different answers every single time, right? I want it to be the same thing.

[00:02:09] Given the same input in, I want the same output out every single time. That is absolutely essential with Redux.
>> Brian Holt: Okay, so you're gonna have one rootReducer, and then inevitably that rootReducer is going to dispatch to other reducers. So to borrow a Flux terminology for those of you who are familiar with Flux.

[00:02:34] The rootReducer is pretty much the dispatch function, right. It's gonna take in and that it's going to give that off to another reducer which is actually gonna take care of the transformation. In this particular case, we have no other reducers yet, we're just instantiating our rootReducer, okay. Two other things about the rootReducer that you have to know.

[00:02:54] It needs to take care of the DEFAULT_STATE, which is what we've done here. This is ES6 to say, if state is undefined, if this is called without state, then the default state is going to be made state, right. So if state is undefined, then it's going to be this, right.

[00:03:13] Here at the search term with being empty string, okay. So it needs to take care of this DEFAULT_STATE. Cuz the first thing that Redux is gonna do is it's going to call the rootReducer with no state, to get the initial state, okay? Okay, the second thing is, is it needs to handle actions that it doesn't know what they are, right?

[00:03:36] So in this particular case If it doesn't know what the action type is, then it's just going to return state, right. So if I call this with some random action and it's just gonna say, cool, I don't know what it is here have the state back, right. That's the second thing that it has to has to do.

[00:03:56]
>> Brian Holt: Let's talk about what actions are for a second. Action are objects, and that's really at the most base level what they are. They're gonna have a type which is going to be a string, right? And, they're gonna have a payload which is going to be a thing, right.

[00:04:15] It could be a string, it could be a number, it could be a boolean, it could be another object, it can be any number of things, right.
>> Brian Holt: And furthermore, they don't actually have to be anything. Nothing is enforcing it to look like this. It's just a really good idea to make it like this.

[00:04:37] This is called a Flux standard action, which is a defined way of dispatching actions. So if you follow the the Flux standard action way of creating actions then things that are created for Flux and things that are created for MobX and all these other kind of state management systems, are also going to work with your system, right.

[00:04:57] That's what the idea of using Flux standard actions is for. That's why it's always called payload, it's always called type. There's two others that we're not gonna worry about, which is error, which is gonna be something else. And then the last one is going to be metadata. Which is gonna be an object of other metadata that you wanna include with your action.

[00:05:18] Again, we're not gonna use these today. We're just gonna use type in payload.
>> Brian Holt: Okay. So here we have basically the most basic reducer that we can have. Okay, now I want you to go and create another file called store.js.
>> Brian Holt: Looks like my notes are wrong here.

[00:05:47]
>> Brian Holt: Which is unfortunate.
>> Brian Holt: So you're going to import.
>> Brian Holt: { CreateStore } from redux, and we're going to import reducer, well what ever you can call it, import reducer from ./reducers. I'm gonna say const store = createStore(reducer) and then we're going to export default store. [BLANK AUDIO] So there's not usually gonna be too much to the store part of your app.

[00:06:43] If you're gonna do any other configuration like introducing middlewares, which we'll talk about momentarily, that stuff is gonna live here. But usually there's not a whole lot to store.
>> Brian Holt: Okay, I want you to create another file called actions.js.
>> Brian Holt: And what we're gonna do here in actions is we're just gonna say export.

[00:07:14] Const SET_SEARCH_TERM = SET_SEARCH_TERM.
>> Brian Holt: So this is something that I do and I would say something that is common but not something that you necessarily have to do. Rather than, this is gonna yell you for not making it. I'm just gonna do blah = blah, I don't know.

[00:07:45] Anyway, is gonna yell at you for now because when you have one export it wants it to be default, right? And this is a named export. so I would say for now ignore it, it will fix it. Because eventually we'll have more than one action type. Okay, so the reason why I do this this way where I have these constants in this file is we're going to be referencing SET_SEARCH_TERM in multiple different places.

[00:08:13] So it's good to have that reading from one particular source. You don't have to do it this way and in particular, when we start doing with flow, it will become mostly irrelevant. But I will still tell you that I think this is a good idea. It is, sometimes, useful to have this be a variable instead of it having like just referencing the string literal set search terms.

[00:08:35] So I will say that this is a common pattern so I encourage you to follow along and then later make a decision of whether or not you wanna follow it.
>> Brian Holt: So this file is just gonna be a bunch of constants being exported and that's it.
>> Brian Holt: And often the same thing, they don't have to be, I'm just really bad at naming things and I'm even worse at naming things twice.

[00:08:58] So, oOkay, make a new file called actionCreators.
>> Brian Holt: Okay, and import { SET_SEARCH_TERM }
>> Brian Holt: From ./actions.
>> Brian Holt: And then here we're gonna export a function.
>> Brian Holt: setSearchTerm which takes in a search term.
>> Brian Holt: And it returns.
>> Brian Holt: Type is going to be SET_SEARCH_TERM and the payload is going to be searchTerm.

[00:10:00]
>> Brian Holt: So, again it's gonna yell at you because it's gonna wanna say, hey you only have one export, there should be a default export. Just ignore it for now cuz eventually we'll come back and have multiple exports.
>> Brian Holt: So again, the action creators is kind of optional but I'm gonna say it's not really optional.

[00:10:18] What an action creator does is it takes in, in this case, a search term and then it's going to return to you a well-formatted action that can go straight into Redux, right. So given this or given this input, this is a valid action for it, right? And then this is what's going to go into Redux which is gonna hit the reducer, right?

[00:10:40] It's gonna switch on the action type, right? And then based on that input, it's going to update your store in some particular way.
>> Brian Holt: In fact, let's go back to reducer.js and let's actually make the reducer that's going to do the update here. So we're gonna have const setSearchTerm which is gonna be a reducer function.

[00:11:07] It's gonna take in state and action, and given that.
>> Brian Holt: It's going to return Object.assign empty object state and another object with { searchTerm: action.payload }.
>> Brian Holt: Okay, so Object.assign, if you're not familiar with it, It's gonna basically do a left merge of this object. So this is an empty object so its a brand new object so we're not modifying state.

[00:11:55] This is key, do not modify the original state, right, you need to return a new state, not modify the old one. Even if you say like, state.searchTerm and then return that. Don't do that either, that doesn't count, don't do it. You're gonna run into a ton of problems.

[00:12:15] Mostly that your stuff won't update because it's just gonna do a shallow check to see if the states changed or not. And if it's the same object that's being returned because of the shallow check, it's gonna assume nothing is changed. So, you must return new state. Let's emphasize that again.

[00:12:31] You must return a new object. Don't return the old one, okay. So new object. We're going to merge all the state that was in there previously. We don't wanna overwrite anything that's already in state, right. And then the last thing, the only thing that we wanna overwrite is the searchTerm.

[00:12:47] So this one's going to be the most salient. So this is the one that's going to actually end up being in there. So this is going to override whatever searchTerm that state had in this new object, right? Object.assign this came with ES6 so that's all that that does.

[00:13:04] So now we've created this function here setSearchTerm. So now we need to go right into our rootReducer, into inside of the switch statement. So here we're gonna say case SET_SEARCH_TERM. I guess we need to go import that as well. So up here at the top SET_SEARCH_TERM from ./actions.

[00:13:39] This is why I was saying that you need to use SET_SEARCH_TERM in multiple places, that's why I like having one constant to represent all of them. So you don't have a fat finger problem. I have fat fingers, so that's why.
>> Brian Holt: And then here, we wanna return setSearchTerm with state and action.

[00:14:02] Okay, we're getting a lint error here
>> Brian Holt: And that's because this is a one-liner, right, and all we're doing is returning so if you remember, you can do implicit returns and with A‌i‌r‌b‌n‌b‌'s configurals you have to.
>> Brian Holt: And get rid of these ones down here at the end.

[00:14:31]
>> Brian Holt: So again, all I did was make this a one-liner. This is now an implicit return. So now we have the SetSearchTerm, this is also reducer, right. So the root reducer delegates to the SetSearchTerm reducer. I just wanted to make you familiar with that terminology. A reducer is anything that takes in state and action returns new state, that's the whole contract there.