Complete Intro to React, v6 Implementing ThemeContext and Q&A
This course has been updated! We now recommend you take the Complete Intro to React, v8 course.
Transcript from the "Implementing ThemeContext and Q&A" Lesson
>> So now we have this theme. Let's go into search provider, or sorry, search provider. We're gonna go into SearchParams and we're gonna make SearchParams be able to change what the theme is. Our theme is only gonna be used on buttons because I'm a designer and I thought that was a good idea.
[00:00:23] That was sarcastic, I'm definitely not a designer, as you can see by all the things I have designed for you. So at the top here, SearchParams, useState, useEffect and useContext. Nice little hook, that's useful for us. And then here we're going to import ThemeContext from ./ThemeContext. Now, here's the fun part.
[00:00:55] We can just say const [useTheme] = useContext(ThemeContext). And lo and behold, I now have access to the theme that's available everywhere my application. I'm just able to yank it out of context. This didn't come from props, this didn't come from state or anything like that. It came from the context.
[00:01:52] And then inside of that I have an object. That's what the double curly braces, it's actually two separate sets. It's not that they mean anything together. And then style we just give it a style object, right? So for background color I could do even just color if I wanted to change the color of the text.
[00:02:10] Anything you would put like in a string right, for HTML, this just comes in as an object. Okay, and now if I head back over to my page notice that the button now is what, dark blue. Or I can come in back to App.js. And if I change this to be, I don't know, what's a different color, pink.
[00:02:38] Now it's pink. So does that make sense for what context is? Now there's this universally available context that I can access anywhere my application. So is the returned value from ThemeContext or from context in general, the same as hooks? And the answer is not necessarily. So let's go back and look at app.js.
[00:03:01] What am I putting into the theme provider here? Theme, what is theme? Theme as what's returned from useState. So it's literally what's coming out useState because I put it there. But let's say I had const theme = green. And I put it in there, it would be green, right?
[00:03:24] It's basically you can think of context basically as like a wormhole that just connects two different points in your application. Whatever you throw in one side, it's gonna come out the other side. So whatever you put in is what you're gonna get out. Does that answer your question?
>> And then probably it helps them a second part of that question would be when you actually invoke useContext in searchparams.js, what does that return?
>> Whatever you put in. Right like so, the let's go back to look at the, I'll just split it so you can look at both the same time.
[00:04:01] Whatever you put in here, this is app.js, is going to come out where is, I'm in SearchParams, right? Yeah, whatever I put in here, comes out here, or here rather.
>> Thank you.
>> Yep, because it's a hook on this side, it's gonna be a hook on this side.
[00:04:25] But if it was an object on one side it'd be an object on the other side. Good question, another question asks can you have multiple contexts? Absolutely, you can go in, let's just look at app.js. I could have multiple layers of context here. I could have one context that encapsulates a whole thing kind of like Redux, right.
[00:04:50] You actually already have some context in your application because react router is using context extensively. That's how links and stuff work, because it's all reading stuff off context. Another thing that you could know but you don't really need to, I can have multiple theme contexts. So if I wrapped details on one of the SearchParams in a different one, I could give one pink and one orange, right, and it would read for those.
[00:05:17] Or I can even just do this. So, we're in SearchParams, can I do this. And all right, so what is the color of my button gonna be when I go back? Is it gonna be dark blue or is it gonna be green? Technically, they look like they both apply, right?
[00:05:47] It's gonna pick green and the reason why green is closer, closer in like the rendering tree. I have never used that in production, it's a nifty party trick. I guess I go to dumb parties,. But you can have multiple layers there, infinite layers I suppose. Yeah, file that under never used.
[00:06:10] [LAUGH] That's what I'm trying to say. Okay, so I wanna show you how to use, cuz this is a hook. Which makes these very pleasant to use if we go back to details. Not details, to SearchParams. This is the hook, this makes it very easy to use. It's a little less convenient to use inside of a component, like a class component.
[00:06:43] But let's go ahead and see how you do it. So let's go back to details. We will want to make our other button respect the color, right? So if I go to Luna, I notice her button is still red, right? I wanna make them both blue at the same time.
[00:07:04] So how would you do that? Well, you would come in here and you have to first import the top, import. ThemeContext from ./ThemeContext. Then down here inside of your button, this one, It's gonna get a little strange, but stick with me for a second. You're gonna say ThemeContext.Consumer.
[00:07:43] Okay, inside of that, you basically have to make a new function, right? Remember, functions are components. So I'm gonna make a new function in here that's gonna take in the theme. Okay, then that's going to return a new button. And actually it's just gonna be this button, so let's just move this up.
[00:08:18] Okay, and now I have this theme available to be used inside of this like little ThemeContext.Consumer This might look a little strange, you could also have made this ThemeHook, Right, and then here you're gonna say, style = same thing that we did last time. backgroundColor themeHook(0), right because this is an array and we want to get the first thing.
[00:08:52] But if I just wrap this in square brackets and call it theme, then I can just access that automatically. So like I said, this is a mess, right? I feel like this is kind of difficult for my brain to parse. I kind of have to look at as like, okay, this is coming from here.
[00:09:13] It's context, blah, blah, blah. Whereas the use context, very straightforward, this is coming out of context I'm getting a hook out of it, blah, blah, blah. But this is how you do it with class components so less convenient for sure. But let's go make sure it works. So if I click into Luna, you can see here and now Luna's button is blue.
[00:09:32] Let's head into SearchParams. I wanna make it so here underneath a breed I wanna add a theme selector where I can select all the themes of my buttons in my web application cuz I'm good at making web applications. So that's what we're gonna do. We're gonna grab the setTheme out of the context as well.
[00:10:01] We just did that here on line 14. And we're gonna make another drop down. Right there above the button, label html4=theme, html4. And we're gonna make a Select value = [theme]. onChange = e setThem[ e.target.value]. Do the same thing again but for on blur. Okay, and then we're gonna have four options in here or however many options you wanna put in here.
[00:11:01] value = and we'll say, dark blue. As long as these are valid CSS colors, you can put whatever you want here. Dark blue, so I'll make four of them. You can do, yeah, whatever your favorite CSS colors are. Did you know that Peru is a color? It is, you're about to find out what color of Peru is, chartreuse.
[00:11:32] My favorite trivia question is do you know what color chartreuse is? And if you ask me right now, I honestly do not remember. I can't even pass my own trivia questions. And another favorite of everyone is medium orchid, not dark orchid, not light orchid, just right. Medium orchid.
[00:12:03] So nothing here you haven't seen before, the only difference is is this is using context. So now what we would expect is I can change the theme. I'm gonna change the button, that's fine on the same page. I could have done that with useState but I'm also gonna change the color of the button on Luna's page or the details page.
[00:12:19] So refresh, dark blue, change that to Peru, it's a lovely shade of Peru. But now, if I click into Luna, notice that her button changed colors as well, why is that? Well, let's think about where that state actually lives. Go back to app.js, where's the theme? The theme is here, it lives above the SearchParans.
[00:12:47] So even when it gets unrendered, it gets unrendered from here. This state never went away. So it's still set to whatever it was set to here in SearchParams. And it's doing that through context. Despite the fact that there's no explicit connection between this and SearchParams, it's using that wormhole of context to go from one place to another.
[00:13:12] Because keep in mind every time that I blow away SearchParams, let's actually see that. If I change this to dog, and then I click on Search whatever and I get new dogs, right, so these are all dogs now. If I click on Angeline here and then if I go back to the homepage, is dogs still going to be selected in my select?
[00:13:37] No, because it lost all that state because it got unrendered, right? Every time that I unrendered SearchParansm all of its state disappears into the ether and the user has to rerender that. So if I wanted to keep this between page loads, I'd either have to keep track of them here in app or I need to use context in some capacity.
[00:13:54] I would probably just use a state here, and then I would just pass it into SearchParams.