3.3 Write Action Creators
When we wrote our reducers, we just passed them actions created as regular objects. However, it's much easier if we use action creators: functions that create and dispatch action objects. We'll write a few of those in this lesson.
1.Introduction2 lessons, 04:39
2.Get Started With Redux6 lessons, 41:43
3.Create React Components8 lessons, 50:18
4.Application Structure9 lessons, 56:09
5.Implement the App9 lessons, 1:31:34
6.Conclusion1 lesson, 01:32
3.3 Write Action Creators
In the previous lesson, we created a basic side bar shell. But it doesn't actually do anything yet. So in this lesson let's actually do something. A very basic understanding of a redux application could be that the state changes and then the app rerenders. Now because we're using react to do this, react only rerenders the smallest part necessary of the application but that's what happens. So we've seen how we can have actions that actually change our state but we haven't actually used actions to change the state and then rerender the application. So let's define a few actions that will take place on our sidebar here. So, I'll put our actions at the top here. Now there are a couple of different actions that we want. The first big obvious one is add deck, right? Whenever the user gives us a name for a new deck, we want to run the add deck action. However, before we get to actually adding the deck, there are a couple of state changes that will affect the UI of our application. Now if you look at the sidebar right now, we have a list of decks and then we have this text box. And the way we've built the sidebar, we can choose to either show or hide this text box. So the behavior we're looking for is, we're gonna have a button on the toolbar at the top here, that will allow us to click to display this text box. Then we can type in the name for a new deck, hit Enter and the text box will disappear but a new deck will appear in our list of decks. So, we need to manage the showing and hiding of this text box through our application state. And so we're gonna need an action to show and an action to hide this text box. We'll call these actions, SHOW_ADD_DECK and HIDE_ADD_DECK. Now remember actions are in the form of objects, right, so we'll have an object here with a type of ADD _DECK. And this here could be our ADD _DECK action. However, it's convention within Redux application to create action create or functions that will return our action for us. So instead of dispatching a raw object like this, let's create a function. So we'll just have a constant here, and we'll call this function addDeck. And it's not going to need to take any parameters. It just needs to return an object. Now with ES6 arrow functions, we can't just return an object with raw curly braces like this because curly braces define the block that follows the function. So we just have to wrap those curly braces in parentheses, and now we are actually returning this object. So in here we will just to type: 'ADD_DECK' and that is our add deck function. Now actually it's not quite that simple, we do need to take a parameter here and that will be the name of the deck that we're adding. So let's say the type is ADD_DECK and the data is the name. So now let's do the same thing for SHOW_ADD_DECK and HIDE_ADD_DECK. Now you can name these functions however you'd like. I'm just gonna call them showAddDeck. I realize it's kind of a weird name, but it'll do for our case. And this will just return the action SHOW_ADD_DECK. And then I'll duplicate this, and we'll change this to HIDE_ADD_DECK. So those are our action creators. Now, we're also going to need a couple more reducers here. Let's create another reducer underneath our cards reducer here. And this is going to be a deck reducer. Of course it will take a state and an action. And of course inside this reducer, we'll do a switch statement and we will switch on action.type. And right now, there's only one case to manage and that is ADD_DECK. So, if we're adding a deck, let's create a new deck here. We'll say newDeck is going to be an object, here. We'll set the name equal to action.data, and we can set the ID equal to +new Date. That's really only need for now. In fact that's so small, I'll put it all on one line. And then we can just return state.concat and we will concat on our new deck. Excellent. Now we also need a default and we will either return whatever the current state is or an empty list. Okay, so now let's add our decks reducer here to our list of reducers in combined reducer. We need one more here and let's create the addingDeck reducer. Now this very small, very simple reducer, is just going to manage whether or not we are currently showing the ADD_DECK text box. Of course it will have a switch statement in it. Let's switch on action.type. And this time we have two actions to consider. We have the SHOW_ADD_DECK action to consider and we also have the HIDE_ADD_DECK to consider. If this action is SHOW_ADD_DECK, that means we want to show the adding deck text box, so we'll return true. If the action type is HIDE_ADD_DECK, that means we are finished showing that, so we'll switch that to false. And for the default, what do we want to do? Well you might think this would be a little bit trickier but it's actually a simple as our previous defaults. If there is some state value we want to return that, right? Because if this is not either SHOW_ADD_DECK or HIDE_ADD_DECK then we would just wanna keep whatever the current state of this property is. So that could be true or false. If it's true, we'll return true. If it's false, we would actually go onto the second part of this if statement. But that's gonna be false as well. And the reason we're doing or false is because at the beginning when redux first creates the store, this function will be called with a state of undefined. And so we wanna make sure we actually convert that to a boolean. Actually convert reminds me what we could do to make this a little bit simpler is just use a double negative here at the beginning. So this way if it's true of return true. If it's false, we'll return false, if it's undefined, we will also return false. So that is our adding deck reducer. Let's add it to our list here. So, we'll say addingD eck. So now, we have all these pieces in place with our store. We're ready to actually use them. Right now, we're just rendering once, at the very bottom of our application. But let's wrap this in a run function, so this way we can run this whenever we want. And in here, what we can do is say let state = store .getstate. And then instead of hard coding this array inside of decks, we can pass in state.decks. And instead of hard coding this boolean value in, we can pass in state.addingDeck. And now what we can do is, run this function at the beginning, and then we can also say store.subscribe and we can call run whenever the store changes. Now if we come back to our code right now, we can see okay, we've got an error decks is not defined and let's see where this is. It looks like, okay right here in our store. So if we set up to our store, here we have decks here but did we misnamed the reducer function. Okay, yeah we just called the Deck, good. Let's save that change and now we can see that everything is just going as you might expect. Now we can see our actual actions in place here if i give us a couple of global functions here. Let's say window.show. And we'll have a function here in what we'll call store dispatch. And we will dispatch the showAddDeck method. And let me also create a window.hide method. And this will call hide Add deck method. And one more, let's create window.ad. And this will call addDeck and it will just pass that new date.to string. Okay, so now we should be able to see these in place if I call these functions from our terminal here. So if I call show, notice what's happened here. Our state has changed. And so we actually have our text box showing here. In fact you can see this a little better if let me in the run function here, I'll just do console.log state. All right, so you can see from the first time it runs. We have cards as an empty array, decks as an empty array and addingDeck is equal to false. However if I call show, you can see that now we rerun the run function, and addingDeck is now true. We could actually type something in here, and eventually, we'll be able to hit Enter, and call our hide and add functions together. However, let's do this separately. I can call hide, and notice addingDeck is now false. I can also call our add function, and notice what happens. Our state gets printed and we have one item in our decks array. If we do it again, you can see we have a second item. And now look, we can see these items printing here in our list. We can see these items printing here in our list. So, although we don't actually have a completely working sidebar yet, we've started to wire our sidebar together. With some of the stage and action creators and we can see our application coming together. Now in the next lesson, we'll actually wire these actions into our sidebar so that instead of performing them in the console, we can actually do them through the UI.