Unlimited WordPress themes, graphics, videos & courses! Unlimited asset downloads! From $16.50/m
React redux 3
  • Overview
  • Transcript

2.5 Challenge: Split a Reducer

Split this reducer function into two sub-reducer functions and then combine them with Redux.

Here’s a hint: use Redux.combineReducers().

Related Links

2.5 Challenge: Split a Reducer

It's time for challenge two. This challenge picks up where challenge one left off. We have our reducer function here, which has cases for add cart and deck and also a default case. What this requires is that we split this reducer function into two sub-producer functions and then combine them with redux. So just a reminder, you can find a link to this CodePen underneath this video. Let's go ahead and fork it, and I will rename it to MySOLUTION. And of course, if you want to do this yourself, go ahead and pause the video now, because I'm gonna show you what the answer is. Notice that we have a little hint here is Redux.combineReducers. Redux has this combineReducers function, which makes it easy for us to combine multiple sub-reducer functions into one bigger reducer. So, what we usually wanna do is have sub-reducers for each one of the top-level properties of our state. In our case, we can see that we have two top-level properties in our state object, cards and decks. In fact, if we were right down here to do console.log, our state would be able to see right here that these object has a cards array and a decks array inside of it. So basically, we need two sub-reducers, one for cards and one for decks. So, let's go ahead and create a function here, that we're gonna call cards. And sub-reducers will take a state and action, just like the parent reducer will. But instead of this state being the whole state, this state is just going to be our cards array. So, let's go ahead and copy our switch statement from this function, and we're gonna paste it into this function up here. And, let's see, what can we do here? Well, first of all, let's just delete the whole add deck section, because we don't need to know about our deck, at all. Secondly, let's look at the default case. We can return the existing cards array, if there is one. But if there isn't, let's just return an empty array, because that is the default empty state for our cards. Okay, this is good because this means that when our state is initialized, and this default case is called, then this empty array is going to be used. So, what about our ADD_CARD case? Well, we still need to create our new card in the same way. But instead of returning an entire state object, we just need to return our cards property. So, we kind of don’t need any of this and this. Now, we do need something a little different here perhaps. First of all, state.cards is not going to exist, it's just gonna be state which is that card's array. So, this might look like the right thing, however, we can actually shorten this up a little more and here's why. When our state is initially created like when we do reducer.undefined, we have to call reducer with undefined state, and an empty action, in that case, our default case in our switch statement here is gonna be run and we're gonna return an empty array. So by the time we start calling and ADD_CARD action, this state is already going to be an empty array. So, we don't have to check to see if it's an array. What we can do is just assumed that it's array and go ahead and concatenate our new card onto it. So this become simply that, and if we wanted to we could actually make this even smaller we can just take our new card assignment here, and just paste it right inside there and make this even shorter. And there we go so we just can concatenate our new object right in there, and that is our cards reducer. So as you might guess, we're gonna do something pretty similar for our decks reducer. And actually, let's just use this reducer function and convert it into the decks reducer, so we can get rid of our ADD_CARD case here. For the default case, instead of returning an empty object, we will return an empty array and then we can do the exact same thing for our return. We will return state.concat, and we will pass in our new deck. And I think this is actually, the cleaner look than what tried to do up above. So let's go ahead and stick with that. So that is our cards and decks reducer. But we need to combine them into one reducer and we can use reduce.combine reducer. So down here lets do constant reducer equals combined reducer. This is a function that takes an object as you know, and each one of the properties this object refers to the sub-reducer. So we can say decks and cards, and we'll use the ES6 shorthand assignment syntax there. So now, if you look over here, you can see that we're still getting our console.log lines. Notice something a little bit different, though. We have initial state being set to false. State with cards and state with decks is true, but inital state is false, and I think you can expect this to happen. This is because we're checking in our initial state to see that state.cards is equal to undefined. But right now state.cards is actually an empty array. So what we could do instead is say, state.cards.length equals zero, and now you can see the initial state is set to true, and so you know that our state is exactly how you would expect it to be when we create our initial state. All right, so that is the solution to challenge number two. We successfully split a reducer into smaller reducers, which, once you start getting bigger applications, makes this much more manageable.

Back to the top