Check out a free preview of the full React and TypeScript, v2 course
The "Context API Exercise" Lesson is part of the full, React and TypeScript, v2 course featured in this preview video. Here's what you'd learn in this lesson:
Students are instructed to refactor the Packing List application to use the Context API and useState hook.
Transcript from the "Context API Exercise" Lesson
[00:00:00]
>> And so the cool part, you can also do some interesting things like give yourself custom hooks as well that are wrapped around this, you don't actually have to pull in dispatch either, and that'll all theoretically work as expected. But we do have to do a little bit of what I think is fair to define as shenanigans in order to get the context API to work.
[00:00:21]
Now again, for those of you who agree with me in the chat and in the room, that forcing it is not great, but maybe acceptable. We will look at another option and the other way. But what I would challenge you to do is we have another example, the packing lists app.
[00:00:42]
They'll show you real quick. Where you're gonna try it out. The twist on the theme this time is that it's just gonna use, use state. So same idea, but instead of dispatch, we're gonna use state. The nice part is it does save you from having to do that React at dispatch.
[00:01:02]
React.setstate action and then the type, because you're just gonna pass. But you'll have to do it in the context once, but then you'll kind of have it in place. The only thing that I need to call out is that there is a with TypeScript branch that you have to use.
[00:01:18]
This is an application that was in case we felt like pointing out from JavaScript to TypeScript also existed, but there is one with TypeScript totally set up. So if you look in here, I did some of the setup already, just simply cuz no one needs to watch me retype the same stuff I just typed.
[00:01:40]
So I've got the createContext, it started out with a null I've got the provider set up, just triple checking. It is wrapped around the index component. Most of the non-type script parts are set up for us. So now, we can kind of do the other piece, which is I can pull in all of these helper methods that I'll need as well, and we can say that this will start out as initial or getinitial state initial items.
[00:02:12]
Cool, and so like that is, you know, the initial part. None of this is hooked up to anything and still no getting passed through and all those things but like the non TypeScript parts of this, other than the fact that they use state for having an array that we saw earlier, but actually this returns an item array.
[00:02:27]
So like if you had a function that always promise that it was gonna return not promises a tricky word not return a promise that has like, but then TypeScript would then cast it in just as we saw before. But just to be explicit, here it is. So that's the context of that we just saw a second ago.
[00:02:46]
Let's pull in the state management pieces from application, because we're going to move it in here that's already in place, but we'll grab it. And these are all the things that we're gonna pull out as well. And I'm not gonna save the file yet because it's gonna start crashing stuff, but we can pull it in to context TSX.
[00:03:10]
And just make it available, so we can stop the prop drilling and paste it all in. Now there is a little surprise in there. You're staring closely enough and you can see it. If not, I will make it obvious to you in a moment. But we have this in place and so we've got all these features.
[00:03:29]
So now what we really want to do is be able to kind of like pass those through all of the context. So really before when we were just using the reducer use, reducer. There's just one dispatch right because like we can't just batch all sorts of different actions, we need to have like some kind of method for each one.
[00:03:51]
We need some way of like bundling these all together in order to thread them through the context API. So we can say in this case we'll say like const value because that's gonna be we pass into the provider down there. And we'll say that this is like items, and it's our unpacked items.
[00:04:14]
Packed items, and we've got was it add, update, remove and then mark all as unpacked, right? We'll take a look at the second. To mark all is unpacked, so that'll be everything bundled together real nicely, and we can pass it in to here. This is where the yelling starts, because it's like, yo, you told me value is null.
[00:04:45]
Yeah, that's true. So here we'll say, but as what? Before I could just say dispatch with the action types, here I can't write. This is one of the reasons like I like use reducer a lot, especially because the number of things I'm doing like this is a case where again like.
[00:05:07]
I might have reached already wanted to show you both because like, sometimes you fight the army, you fight the battle, the army you have, right? One of things I could do is literally again to kind of hit that running theme rather than wreck my head and sit there and try to like get it right and watch my code.
[00:05:22]
Now, compile the answer a lot of times. It's just stealing it from your own code, right? Let typescript give you the answer, so that you can give TypeScript the answers somewhere else. So we can grab this, and I can make this his own type, right? I can call it.
[00:05:47]
Now we have this, and we can see that like this is verify that those are both the same thing, right? Cool because we don't get a compiler. This is how we know that they are both valid, and they are simpatico with each other. So that all kind of works.
[00:06:07]
It's great like there are fun things that you, if these were in the same scope, you could do stuff like, I don't even know if you can write a type inside of a, it's smaller shape. Yeah, I'm pretty sure, so I'm getting yelled at, but I'll show you what this looks like if it was up and out of there.
[00:06:25]
You can say type. Right now, we'll figure out, type of value. And you can see that that is a way to figure out the type based on an object. This is a regular old JavaScript value, it has determined the type, and it's allowing me to then make a type on the fly dynamically.
[00:07:02]
That said, we still have that closure scope problem that we had before, so, both work. I use this a lot especially with arrays for statuses we have a bunch of labels of running, paused, terminated. I want those to be types, so I can make those union types like you saw with the actions, but I also need them as values that I iterate over.
[00:07:23]
So a lot of times I'll do like loading, error, success for whatever it is. I do as const which means this is an array that's never gonna change. It's kind of like when we saw number, number, number. This is not an array that you can push onto or pop off of this is a static array and then if you did.
[00:07:59]
You would get this full array, but then if you did. That's the key of type of status, yeah. This will give you the full array of them that you can kind of like pick one of in this case and then if you said for a raise the keys or numbers, think I got.
[00:08:24]
See, got a union type based out of that array, right? So this is saying like go through all the keys which are numbers 123 gives you a status and so now I can like set them very clearly based on this. So if you have a value that you need to use in JavaScript, and then also a type, you can kind of dynamically derive the type from the value.
[00:08:43]
It is not just a, if you cast your types and values, you can also pull types out of values as well. Cool, but we were gonna do the copy-paste method for now because like, again, we want that in the top level scope. And this also, I think is a little bit more sane for our purposes.
[00:09:00]
So pass it in, we say that listen, this is going to be everything I promise I'm going to do it, two lines now. And again, we will look at another solution to this in a second. But we have it in place because like honestly, this one does work, like when I show you the other one you might still choose this one, that's why I'm like keeping it for a while.
[00:09:18]
So we've got that like in place, it's getting passed through, everything seems mostly good applications angry me because I literally removed all these functions. So like we've got to still have to do that refactor, absolutely, but we will do it with the aid of TypeScript in this case.
[00:09:34]
So could I? This was just getting items and showing the count. This one has one function, could I thread them through with use dispatch? I totally could. You can later. I'm gonna do the ones that have multi depths of layers of items. Item list to the individual item to actually showing that to having the actions on the right button.
[00:09:54]
So I'm going to do the two item list. These aren't really worth it, but I can pull them in here, so we'll say use context. Did I export everything. Items context here I'm gonna grab just items add, and what's the other? Just mark it all is unpacked. Cool, so you can see these are happy.
[00:10:36]
I don't need to pass these props through anymore, right? Because I can pull them when I need them. Let's actually pass these in too. That way, I can just reuse the same component. Cool. Still angry with me cuz it was expecting update and remove. So we can say like, hey, wait, what if you just didn't worry about this anymore?
[00:11:05]
No, we don't have to pass him in here. And again, it's kind of just following the errors. It's a little cathartic at times. Versus like, I don't have enough test, let me keep checking and so on and so forth, right? And kind of just follow the compile errors through.
[00:11:26]
I don't need them here, and keep that because we're gonna use that functionality and second they don't need to be in the type. So now here we can do useContext, Let's update and remove. Awesome, and if we go fire up the app, And again, other than when I'm dealing with third party libraries where I forget that they need a certain string, will I open a pull request saying that, it there's no hashtag at the beginning.
[00:12:17]
Maybe you try that first before you blow up. I might later. Just for glory and or my own misunderstanding of closure scope for a hot minute there. Generally speaking, I can feel confident just in my editor without the need to, like, jump back and forth. Should you have tests?
[00:12:34]
Absolutely, you should have tests. Do you need as many for all these educations? I was feeling comfortable, and a lot of times while I'm using TypeScript, I feel comfortable just doing the refactor. So now, we can see that we can update one, we can remove it. So to stream with me.
[00:12:55]
There it is at the bottom. Cool, everything works. I can check boxes. I can edit a name. Awesome.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops