Check out a free preview of the full Complete Intro to React, v8 course:
The "Context" Lesson is part of the full, Complete Intro to React, v8 course featured in this preview video. Here's what you'd learn in this lesson:

Brian discusses Context as an application-level state that primarily replaces Redux and should be used cautiously to maintain an explicit data flow. The React BrowserRouter and QueryClient utilize context under the hood.

Get Unlimited Access Now

Transcript from the "Context" Lesson

[00:00:00]
>> So context. Right now we've been looking a lot of very local state, right? An example of local state here would be do I show the modal? Do I not show the modal? That's really only important to the details page. Or in other words, if I'm on the SearchParams page, I don't need to have this show modal available anywhere but being inside of details, right?

[00:00:29] So local state apps or UI state would be another term for that. But sometimes we have things that like is global app level state. And the easiest example is that if I had a user that was logged in, right? Every page cares about which user is logged in, and that would be app level state.

[00:00:50] So, there's a bunch of ways you can handle that. You do not have to use context, or Redux, or MobX, or any of those things. I literally could just go to App.jsx and I could just say const [user, set user] = useState(null). And then whenever a user logs in, I would just track that under here, right?

[00:01:16] And then I would just pass it in from here. So I'd say user={user} and user={user}, boom. Now suddenly everyone has access to the user all the time. Awesome, done, right? And if my app was this big, very valid that I would do it this way, right? But now imagine I have 40 different pages and 39 of them care about what user it is.

[00:01:43] The other one is the about page. Maybe the about page cares, I don't know. Maybe you have a really cool customized about page, in which case you probably have too much time on your hands. That's my opinion. Anyway, context, this is where context becomes extremely useful to you, right?

[00:01:59] Context is going to be this app level, generalized state. Now, this is literally the last lesson in the intro to React. I intentionally put this last because I really don't know want you to heavily handedly apply this to everything. Because that's kind of the temptation, it's like, I have state, let's make state available everywhere.

[00:02:19] Bad idea. You really wanna be judicious of where state goes. And one of the benefits of React is how explicit data flows in your app, right? If I have information that's in details I wanna be able to find where it came from, right? And kind of trace everything where that goes.

[00:02:40] As soon as you start introducing context into your app, you get this indirection. You have state that comes from somewhere that it's kind of hard to follow where it came from. So you're getting this general availability of it, which makes it easy to use. But what you're trading off on is that it becomes difficult to find where it came from, and how it was modified, and where the bugs are.

[00:03:06] So in other words, context is a very specific tool, I need you to have a specific reason to use it. So something like a user worthy, literally every page cares about it and passing it around becomes impractical. That is a valid use case for context, you should use context in there.

[00:03:24] But I don't know, if you have two pages that care about the theme, I don't know, something like that, right? Just pass it around like normal state with using props and children and stuff like that, right? So that's my pitch to you. And I'm gonna show you how to do it, and I'm gonna ask you to be judicious of how you apply it, because I might be your future coworker and I will be upset.

[00:03:48] Okay, so basically what I wanna do is I wanna have like, if I click here on Luna, I click Yes, I wanna be able to show that to users on my Adopt Me page, right? I wanna show them a little picture here of the pet I'm about to adopt.

[00:04:06] That's the context that we're gonna use here. So first things, pop over and make a file called AdoptedPetContext. And this can be .js, .jsx. Because we're not gonna major in jsx, I'm just gonna do .js. I'm going to import (createContext) from 'react', const AdoptedPetContext = createContext, export default AdoptedPetContext.

[00:04:55] So you can come in here and give it a default value. But typically you don't wanna have default context. But if you did, this is where you would do it, right? Maybe you have an array of a cart, right? Like an array of items. By all means putting an empty array there that makes some sense.

[00:05:14] And we'll have to do this with TypeScript. TypeScript is going to make you have a default value, but for now, we're not gonna do it. I'll show you in a second, but basically, you'll never have a default value for your context or you shouldn't. Okay, so let's go to App.jsx and make use of it.

[00:05:39] You've already been using context because you've been using BrowserRouter and QueryClientProvider here. These are both using context under the hood, just so you know. That's the entire purpose of these things is to provide context to things underneath them. Okay, up here I want you to import state, or rather useState from react.

[00:06:07] And then somewhere under here you're going to import AdoptedPetContext from AdoptedPetContext, okay? Up here we're gonna say const adoptedPet = usesState(null). Okay? And then somewhere in here we'll just do it under the QueryClientProvider. We're gonna have AdaptedPetContext.Provider and the value is going to be equal to adoptedPet. Okay?

[00:06:56] And then just wrap everything inside of that with that, and there we go. What this is doing, is it's now making this adoptedPet available to any consumer of AdoptedPetContext inside of it. So now details has it available, SearchParams has it available, and they can both use them whenever they want.

[00:07:28] Hopefully you're seeing there's some indirection to this, right? I now have this adoptedPet, which is going into details and going into SearchParams. But the data flow here is no longer explicit, right? Explicit would be saying adoptedPet = adoptedPet, right? But we're not doing that anymore. Okay, you notice we're just passing the whole hook here.

[00:07:56] We're using a hook together with context, you don't have to. You can basically think of this provider on context as a wormhole, right? So I can dump stuff out of it and then later I can go to another part of my app and I can pull stuff out of the wormhole.

[00:08:11] And what happens in the middle is anyone's guess, right? So I'm putting a hook into this, but it could be an object, it could be a number, it could be a string. It doesn't care what type is going into it. It's a method of transportation and that's it.