This course has been updated! We now recommend you take the State Management with Redux & MobX course.

Check out a free preview of the full Advanced State Management in React (feat. Redux and MobX) course:
The "Redux Solution: Undo and Redo" Lesson is part of the full, Advanced State Management in React (feat. Redux and MobX) course featured in this preview video. Here's what you'd learn in this lesson:

Wiring up the undo and redo feature in the Jetsetter application.

Get Unlimited Access Now

Transcript from the "Redux Solution: Undo and Redo" Lesson

>> Steve Kinney: So we're gonna have to change the way we think about our state a little bit, and this is gonna be a fun little exercise. Let's go into that initial states. This is the shape of our store by default. And so we have these items, which is just a big array of items, as well as the filter text and the new item value text.

[00:00:22] But we're gonna need to separate this out, there is now three states of the item collection. There is the present state, there is a collection of all the past states that we can undo too, and there is a collection of all the future states. Which only existed with used undo, right?

[00:00:41] So if you do undo, you wanna implement redo. So you need to keep track in some kind of order. So we're gonna have to move this around a little bit. And so what we'll do is change this to items. This is gonna have three kind of sub-components. Which is gonna mean we're gonna have to change some reducers and touch a lot of things.

>> Steve Kinney: So we'll have items and we'll have past, present,
>> Steve Kinney: And future.
>> Steve Kinney: And these will be arrays,
>> Steve Kinney: That will hold different states in them. And then it will be, there's only one present, that will be the items. All right, very cool. Now this is gonna break everything.

[00:01:30] Right, I can go back over to the app, but it is not gonna be happy times, he says.
>> Steve Kinney: One second.
>> Steve Kinney: It will be happy times if you have two versions of the project open and you're editing the wrong one. It's really great then.
>> Steve Kinney: So let's just fix that.

>> Steve Kinney: And now things are broken. [LAUGH] This is the first time in our live coding when we wanted things to be broken, and we're shocked when they weren't. So here we are. [LAUGH] Things are broken, everything is good. We are in the desired broken state, because if we look at the error message.

[00:02:22] It's looking for items.filter but items is now that object that has past, present, and future. And so it's like, yeah you didn't give me an array. There's no filter. Everything is horrible. I don't know what to do. So fixing this is pretty easy. And I hope, you should get a code smell as I do this, right?

[00:02:43] And the fact there is some lack of dryness to my code. And that's intentional for simplicity right now but we'll talk about how we can make that better. So it's on the packed items container, we wanna say .present.
>> Steve Kinney: On the unpacked items container, we also wanna say .present.

[00:03:05] So there's definitely a lack of dryness in this code, right? What you might wanna do as kind of an exercise for the reader later is it would be great to have a function that then produced this, with the only difference between being packed and unpacked. So you could pass it in what property you were looking for to filter on.

[00:03:20] That's a little too in the weeds for us all to do together. But if your Spidey sense, if your code smell Spidey sense went off, that is a very valid Spidey sense, but we're just not going to do it right now cuz we've effectively, we're back in a working state.

[00:03:34] And we got code to ship. So,
>> Steve Kinney: We have to also fix it on the actions as well. But we'll get to that in a second because I have that planned. Let's add two more actions, right? So, we can have two more constants that we add, which is undo item action and redo item action, right?

[00:03:55] Those are the two things that a user can do when we implement this user interface. So let's go ahead, let's find our constants.
>> Steve Kinney: And we're just gonna add these in. So we're gonna export the const UNDO_ITEM_ACTION,
>> Steve Kinney: And we'll have another one, a little bit of copy paste action here.

>> Steve Kinney: REDO_ITEM_ACTION. All right, very cool, and we're probably gonna need item creators as well. So we'll go ahead and basically we'll just have one called like UNDO_ITEM_ACTION that's going to create this event, and we'll have one called REDO_ITEM_ACTION.
>> Steve Kinney: And I'm gonna put these in the item-actions cuz that seems like a good place for them.

[00:04:53] I could be convinced that maybe they should go on their own file but,
>> Steve Kinney: All right, so I need to pull those in as well.
>> Steve Kinney: We'll pull in UNDO_ITEM_ACTION and REDO. I'm just gonna format that a little bit better. Very cool.
>> Steve Kinney: All right, so we have the action creators.

[00:05:16] We've got the action constants, all right. Next what we probably wanna do is we've fixed the map state to props in both. But we also need to go ahead and what's this other issue that we have?
>> Steve Kinney: We need to fix, so this, if you look in the items reducer, we have this problem that we're gonna need to deal with, which is we're trying to map over the items.

[00:05:42] But again, that's items.present every time. We're going to do some other things in the reducer, so I'm gonna punt on that for a little bit until we get deep into the reducer to figure out, we'll change all those state to state.present. Cuz effectively, what we need to cuz we move the array one child down.

[00:05:57] So we'll get to all of that in a second. But let's implement the container for the undo and the redo buttons.
>> Steve Kinney: So I'm gonna just make a undo redo container. If you don't like that name, you can name it something else. And we're gonna need to do a few things in here.

[00:06:18] I'm going to import connect from react-redux and again I'm likely to mess it up at least once I call it redux-react. So, everyone be on guard for that. We'll also import our undoItemAction, and redoItemAction from actions/item-actions. And now what are the two things that I know I need to make?

>> Steve Kinney: mapStateToPropr except I don't really have any state. It's just gonna be two buttons now that I think about it. So I don't need to map any StateToProps cuz there's no state to map to the props. So I just need a mapDispatchToProps. And that's going to take the Dispatch.

>> Steve Kinney: And I am going to immediately return a bind action creators. Apparently I have a plug-in that automatically pulled that in. That's pretty cool.
>> Steve Kinney: I knew that I had it on my work laptop, I actually forgot that I had it on this one. undoItemAction, redoItemAction and we'll bind that to the dispatch.

[00:07:49] Just one semi colon is enough. All right, cool. And so, I could make a presentation component, but I'm gonna be a little lazy here. Don't tell anyone. He says, on a recorded thing being live streamed. We don't have any state to map to the props. We do have this mapDispatchToProps, and we're gonna just give it a component right here.

[00:08:12] We'll use the stateless functional one, which is gonna take, let's call these undo and redo, just to make things easier.
>> Steve Kinney: So I'm just gonna define the presentational component on the fly here.
>> Steve Kinney: I could theoretically put this on variable as well. I've started typing. This is the decision that I've made and I'm gonna go for it for now.

[00:08:38] So we'll have undo and redo. And all we're really gonna do is make a div cuz we need one,
>> Steve Kinney: Component to start out with. I'm gonna use parentheses so I can just return it immediately.
>> Steve Kinney: All right, cool. So we've got this div, and it's gonna have two buttons in it.

[00:09:02] It's gonna have, let's make the buttons first.
>> Steve Kinney: You're all gonna be shocked and surprised to find what these two buttons' labels are. One of them is gonna be called undo. The other one is going to be called redo. And I'll say onClick, undo, onClick, we will redo.

[00:09:30] I've got a bunch of squiggly red lines. I feel like I should listen to it which is saying hey, you wrote some jsx and you didn't import React.
>> Steve Kinney: All right, so we have, this is now, we've got these action creators bound in there. And so we've got this presentation or component.

[00:09:51] I'm gonna go ahead and just implement it into the application.
>> Steve Kinney: And so what I'll do is I will import, undo, redo container.
>> Steve Kinney: Containers undo redo container.
>> Steve Kinney: And we'll just pop it, let's put it under the new item container.
>> Steve Kinney: All right, everything loads, there it is.

[00:10:28] All right, you're gonna have to indulge me for a second. Sorry. Which is, that's too close to the input field, and I'm not changing CSS. I don't live code CSS as a rule.
>> Steve Kinney: Oops
>> Steve Kinney: All right just a little bit better. I added some margins, so it is not jammed up against the input field.