Intermediate React, v3 useContext
This course has been updated! We now recommend you take the Intermediate React, v5 course.
Transcript from the "useContext" Lesson
>> Let's go to the context component here. All right, so let's hide this again. So, let's talk about the prop drilling problem. You can see here I have a lot of components. I have a level 1 context component, level 2, level 3, level 4, and then level 5, right?
[00:00:26] So this is the parent, child, grandchild, great grandchild, great, great grandchild in terms of the hierarchy here, right? Let's say that I have this, First level I have this object here of James Jamison who's at his email, and I have this user data that I need to get from the first level all the way to level 5.
[00:00:58] Now, if we weren't using context the way that we would do that is we would have const object or person, let's just call it person. And just say like that's an object here and what we would have to do is each one of these, you'd have to say person equals person, right?
[00:01:21] And then here I would have to say props. Person equals, Props.person. Then here I would have to say props, Props equals, beside person equals props.person. Same thing here. So hopefully you're getting the point is that I have to keep handing this down, over and over and over again.
[00:01:58] Let's actually just go through with it so you can feel my pain, cuz before context is around, this is what you had to do. Then finally here I can put like let's put another h5 here, Of JSON.stringify, props.person, All right, so let's just have props here. So you can see down here, finally I got the person all the way down.
[00:02:40] Now, isn't that just an exercise in frustration? So, when it's bad uncouple is, when I was just annoying to type to get all the way from the top level, all the way down to the bottom level. But secondly, it's actually kind of a bad thing overall, because now all of these components, which didn't know or care about person, now I have to individually care about person.
[00:02:59] And so if I wanna move level 3 to be used somewhere else in my application, I have to make sure that person is being passed into there, or else that component, no longer works. I've now made each one of these components that actually really didn't care about props.person, whatever was gonna be in here?
[00:03:17] Now each one of them is kind of tied in this chain, and they have to have it or they break. Wouldn't be better if we could do something different where we could actually just pass it directly from this top level person or this context component directly all the way to level 5.
[00:03:34] And you can, there's a thing called context. So the first thing I'm going to do here is I'm going to create my context. Constusercontext equals create context which comes from react. Wrap. Okay, so that's coming from react here. Okay? So I've created this context, I gave it a default object.
[00:03:56] So if there's no default state, it just gives you this kind of, or sorry, if there's no provided state, it gives you this default state. Normally won't do that, but it's good to know that that's what this object is. That's why you see here that it's James Jamison and not Bob Bobason, okay?
[00:04:15] And then if I go down here to this, I mean you can see here if I actually just delete this. You'll see that this is actually changed to Bob Bobason. Maybe not. Yeah. It's because it's not getting actual real estate. So, in any case, that's what this is for.
[00:04:54] It's for default objects but because we're actually hooking it into a hook, that's not why it's gonna work, okay? So I have this User Provider. This is actually what's going to provide everything in this context to the lower components here, so that's why level 2, level 3, level 4, level 5 can all access these pieces of context.
[00:05:14] But here, inside of level 5, I have this use context which I'm providing the use context from here, and I'm pulling out the user and the set user which I provided up here inside of the context component, right? And that's why I'm able to have data up here.
[00:05:35] So James Jamison, and I'm able to use that down here in level 5. That's why I can even do increment, right? So this is actually incrementing the number here that's being stored here in the context component here in this state, this suffix, right? So this gets around the prop drilling problem, which is what I showed you here with the person.
[00:06:00] And it also gets around the making all these intermediary components care about the person which they shouldn't have to. Now the question might ask me is like, okay, here's a contrived example. What am I actually gonna use this really my application, and I'm going to encourage you to be sparing in how you use context.
[00:06:23] Because one of the nice things about what I did here with person is it's now very explicit where this came from. I know exactly where person came from because I can follow the trail back here I can say, okay, level 5 got it from level 4, level 4 got it from level 3, cuz I can see it, right?
[00:06:42] Whereas here, I just do use context and I pull this in, it's I don't actually really know where this came from. I don't know where the context was set where it's being tracked, who cares about it. So that's indirection. And one of the strengths of react is that it's explicit, it makes it very easy to read and follow.
[00:07:00] So just know that it's a powerful tool that you're introducing indirection to your application, which is hard, right? You want to have as much explicitness and readability and maintainability that your app can have.
>> Is this the same context that we used yesterday for the colors for the theme?
>> So the question is this the same context that we used in the complete intro to react view 6 for the theme, and the answer's yes, it's the exact same concept here. So yeah, steaming would be another good example of some time when you might use context, right?
[00:07:39] Because you have all these various different parts of your application. If you want to switch to dark mode, a lot of your components are going to have to care about I was like, I'm in dark mode now I have to do things differently, right? So that'd be a good example of global application state.
[00:07:51] And that's kind of the key here, is you need to think of things in like global application state. That's when context is useful. What is the second argument of the create context? So you're probably asking what this one is right here. So notice this is actually one argument, it's an array, and this is actually just made to look like a hook, and the reason why I do this is it makes it easier for type script to type.
[00:08:15] So this is the use state hook, where the first thing is the default state and the second thing is the set state. Beside the first thing is actually the hook, contained in the hook. And the second thing is the set value. So in this particular case is an object that returns an object.
[00:08:33] That's how the set state works. So if you remember here, you state returns a, we'll just look up here, returns. The first thing is the user, the second thing is the set user, and this is just mimicking that. So if I had context, which doesn't always have to be a hook, by the way, and all I was checking was a color, what I would have here instead would be green, right?
[00:09:00] So that's what that second thing is, it's just the set state for the state hook.
>> So is the use context like the way it manages global state, similar to the way Redux does it?
>> You're going to use Context in places that where you typically would probably use Redux, right?
[00:09:17] You're gonna use Context and Redux in similar ways, and frequently, you probably don't want to use them at the same time. I would suggest either using Context or using Redux. It's not a hard and fast rule but I would say that's how I'm gonna approach it. And I would say that's a pretty good way to approach it.
[00:09:51] So it only manages to modify this, the user context which is kind of globally available anywhere inside of this provider, right? So it's global to every component inside of there, right? But if I put that down here on level 2, that means that this context component would not be able to access it, right?
[00:10:13] So it's only scoped to everything inside of the provider.