Check out a free preview of the full Advanced Redux with Redux Toolkit course

The "Create Reducer" Lesson is part of the full, Advanced Redux with Redux Toolkit course featured in this preview video. Here's what you'd learn in this lesson:

Steve demonstrates how the createReducer helper method simplifies the process of creating reducers. Builder callback functions that define the cases for each action are passed to the reduce. Mutable operations can be performed on the state object because the underlying libraries create a "WriteableDraft" of the state.


Transcript from the "Create Reducer" Lesson

>> The other kind of piece that we can use is create Action Sibling. So now we're going to talk about create Reducer. Which is if you saw on that slice before, how I just had the properties on that slice, and you want to just pull that piece as well, you can have that too.

It's all yours and mix and match whatever you want. Regular actions are working to create reducer, create actions will work with a regular reducer. It all can work together for you. So, what would it look like if I just want to make a brand new reducer? So we've got this other idea of.

Create reducer. I believe I pulled that in. Yep, go create reducer and we'll just say like count reducer. So it's not the same counter reducer. Some it's a rare time where the typo is a better choice than what I said out loud. So we'll go with it. And if you look immediately like it takes some of the things that we should have seen from that slice that we saw earlier because that again, like we're pulling apart, a slice to figure out what all the component pieces are here.

And so we've got this. It takes some kind of initial state if we look at it. And these are properties on an object. So before you just saw me kind of use that shorthand in JavaScript, but I could say initial state. And it's still angry with me because it's like you need to give me a few more things here and so count reducer as well and we need to we give it this function This function is actually it's actually just an argument for the initial state here, sorry.

This function is a little bit interesting. It's a function that takes this idea of a builder.
>> So the first argument is always the reducer.
>> The first arguments the initial state Yep. Exactly that slice thing that you saw before where we had an object with keys. You can also technically do it here.

The reason that I would caution against it is when you do it in a slice, you have like, the slice itself knows it's the one making the actions So it can wire up all the types for you. When you use create reducer, like this notation is preferred because it will give you better TypeScript support without really having to do anything.

Right? And so if you like the one that we saw on the slice where I just had like add task as a key, remove task as a key. You can do that, and I guess maybe if you're like, you will not, whether it's the helpful hints in your code or whatever, you will not get the same help.

So I would recommend that you do this one. And so this builder is simply has,let's take a look at it. I love the fact that my code editor will give me the answers. Add case, add default case and add matcher. Let's talk about them an order add case is if you've ever used a switch statement, or if you have ever done what I do, which is like as you saw before, I literally scroll down and see what I do which is a series of if statements with returns.

That is one of those cases, right? And then default case is what you can guess it is probably, the thing at the bottom where you either return state, and you don't actually have to define this. This is literally if you actually want to catch the default You don't have to protect yourself against this one at this point.

This is now if you want to. Because previously, you had to always handle the default case because it was just a JavaScript function. And if you did not return state in some way, shape, or form, or do something with it, your function would return undefined. You would set the state to undefined.

Here, because we have this builder abstraction, that's all going to get taken care of for you, so you don't worry about silly mistake. Which, to be clear, like three weeks ago, not this last sprint, but the one before, at least 20 minutes of my life down the toilet.

Right this will solve you save you from that, right?
>> So false case if you don't use it as optional, so it'll just automatically do the initial state for you. You don't do that.
>> Exactly It'll give you like, it'll be like, I don't do anything with this one.

Right, which is no, almost always what you want, right? Because Redux itself is so low level. You don't get that because it's just a JavaScript function. Because you have a little bit more abstraction, right? This will solve that for you. Awesome. So we've got that in place and so we can say ad case.

And what's really cool about this is we handed just one of those action creators so I can say increment and like. Now this is one that will catch it on increment, right? And we give it the state and the action. I'll move fully write this out as a arrow notation function.

Check this out, automatically typed. There's the like, the weird thing that I'm going to talk about. Automatically typed in here automatically typed. Because you gave it the action creator. You pass this in as the first argument that increment action critically made the previous exercise. And so it's like, Yo, let me look at the types that this thing produces.

Cool, core I know what the action that comes out of this action creator is the same way we wrote that return value earlier. It's looking at the same return value, knows what the shape of the type of the action is, and has that ready to go for you.

And looked at the shape of the initial state and just said, that's clearly what this is. Ready to rock and roll. Now wait for it, I promise you that I am not about to write a bug. Do you trust me? Okay, so all I'm going to do is say, no conditional in this case, I'm just going to say, I'm just going to increment that.

I'm just going to mutate it. That key on the object. And that is valid, and that works. I just, and that is scoped to only the state of this producer. Write correctly I can mutate things on this object. You're like I can't use I'm not supposed to use mutable state.

This is your library called Emmer immer is made by the same person created mob X, and what it is doing is it gave you a, if you saw before if we hovered over the state, it's called writable draft, right? And so basically it gave you a copy of the current state.

And it's like mutate this thing as much as you want. Push things onto the arrays. Pop things off, place them even, see if you remember syntax place. Do all those of things. Even if you're deeply nested object, you can find that key, switch the deeply nested value to a different value and it will do all the readable operations on your behalf, right?

So your objects are still readable, But you can pretend that they're mutable. And that like, lie to yourself will work which a lot of times if you in previous chats, we have talked about the fact that like having deeply nested data in like most react applications and Redux applications, is an anti pattern because you spread operator your way down your way back out.

Right but sometimes we live in code bases where like that ship has already sailed and this is the world that we live in right so this is then a pattern that will then save you because that is the most error prone code right and even unit testing that This is doable, right?

If you got some time, because then you've got to still make sure you got to write your unit test. Right, who tests the unit tests? Right so in this case, like having this abstraction here with Emmer, which is just a library, again, you can use any of these things separately, right?

I use them all the time. Like just in a regular use reducer, what have you. We'll go ahead and make your code seem mutable but actually be completely mutable. And you'll notice I didn't have to return anything from this function either, right? So all those edge cases and errors are taken care of for me and handled and I don't necessarily have to worry about it.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now