This course has been updated! We now recommend you take the React Performance course.

Check out a free preview of the full State Management in Pure React, v2 course:
The "Context & useContext Hook" Lesson is part of the full, State Management in Pure React, v2 course featured in this preview video. Here's what you'd learn in this lesson:

Steve demonstrates how to directly pull information from the context API with the useContext hook, without needing to update the state every time.

Get Unlimited Access Now

Transcript from the "Context & useContext Hook" Lesson

[00:00:00]
>> Does it always have to go around application know if it is only a part of your app that needs this right? Like our application we've got the one I used to work on for a number of years had like contacts, but they also had an editor, but those might, I don't necessarily need to read the entire thing and that I can kinda go to the smaller part that needs it.

[00:00:19] Cuz we in case we're gonna move that stuff around. But in this case is a relatively simple application. Maybe this is for a lot of cases is the answer, right? If you've used Redux before, it's usually wrapped around the overall root component as well. Same thing as like react router.

[00:00:33] Typically you will see it here. What happens if you end up needing multiple providers? Or you're just gonna end up stacking them. It's not it feels wrong, but it's okay could you could probably do some crazy stuff with functional programming and composing and piping stuff, but probably not worth it.

[00:00:50] So now anything can hook into the context, which means we can do a little bit of refactoring now And there is nothing scarier than doing a major refactor live coding, but we'll try it out and we'll hope for the best and we'll deal with whatever errors come up.

[00:01:04] So everything is now a child of GrudgeProvider, which has the actual context provider, which has that state management. So anything can hook into it, which means application doesn't actually have access to add grudge or grudges anymore. Right, so and we will likely come back and admire this in a second but really just wanna talk about what we got out of this now, To how to justify the next few moments, what we're gonna do.

[00:01:37] NewGrudge is now this atomic piece that I can move anywhere in the application. It doesn't necessarily need everything to pass down from application. So I wanna make a sidebar and move it over there Cool, it knows about how to add a garage or will know about when we're done.

[00:01:50] Right? The individual garages I need to move them someplace I can just basically say here is the hierarchy. Here's exactly what my application the layout should be. And I'm not necessarily worried about like threading everything through and thinking about it. I'm just basically arranging the application And I can move stuff around and everything will just work it's kind of like atomic and composed with a state management that it needs.

[00:02:12] So let's go ahead and we'll implement it. So I'm gonna save this file whatever you do don't look in your browser cuz we've broken everything, but it's fine, cool so we've got that in place, so what we'll do here is for the grudges themselves, now grudges plural doesn't get Unforgive anymore.

[00:02:30] Because it doesn't need to do that passing along so we can get rid of that. It will get all the, you know, it actually won't even receive the grudges anymore. Because application doesn't have them, applications not passing them in. Right. what it needs to do is it needs to reach into the context and grab them.

[00:02:48] This is where we'll get to use the use context hook. So all I'll do is say const, grudges Let's go back into grudge context, I just need to export it, the actual context itself Right, so now grudges, plural, can basically say, okay, hook into the GrudgeContent, and get the grudges out of there.

[00:03:27] It doesn't need anything passed in. It can be moved anywhere. We don't have to worry about this passing stuff through the component hierarchy. It does make sense. You'll see some patterns where you might have for the list of things just an array of IDs, and then each singular grudge might be in charge of like going and finding that one and it might also have to hook into the context.

[00:03:50] We're not gonna go that far right now. But we can see that Grudges plural doesn't get anything past and it can just hook into the context. Same is true of grudge singular, right? It will get the grudge past and from above which makes sense. Again, we could- We still need to know which grudge this is, we need to pass something.

[00:04:09] Whether it's the idea of which one to go get from the context API, or the whole grudge object. Really, it's about how your data's structured. In this case, we have the full object, we have to pass either an ID or the full object in. So let's just pass in the full object.

[00:04:23] But we didn't wanna thread through that on forgive. Right, and so if we want to get access to toggleForgiveness, it is the same basic idea. UseContext, I'll grab that from the GrudgeContext as well. So it just reaches up into that context that we made and so instead of being called, 'toggleunforgiveness', it's called, 'toggleforgiveness'.

[00:04:57] So again, we say all right, the Grudges be like, "Hey, I need all the Grudges." The individual Grudge can be like, "All right, I need the ability to forgive a Grudge." Right and have access to that as well and they don't necessarily have a path, each one can reach in and grab exactly what it needs in this case.

[00:05:17] Alright, cool, so we've got all that in there The other thing we wanna do is, we're gonna want implement the ability to add a new grudge, but first what we gonna do is we're just going to comment that out for a second to verify that we've works, cuz new grudge is still broken, cuz it's basked in property you passed in.

[00:05:37] Might actually work, unless we actually try to call it. Let's see. Yeah it's there. Alright, cool. So we got so refreshed. I don't have anything yet. So let's see what we got. We've got the context provider. Scott this value array of garages if you don't save files, nothing happens.

[00:06:09] There they are. So we had an empty array as the graduates prop and so I didn't save the file. So you can see that there. They are. You will notice that I am rendering all of them on every forgiven again. All my performance optimizations didn't carry through. The reason for this is there's no real way to know anymore.

[00:06:32] That react memo was looking at the props last time and the props this time. But now it's reaching into context, and it doesn't really know what changed. Right. And so what we are getting is the ability to get a nice clean kinda set up like this. What we are losing is some of that light performance optimization.

[00:06:54] Now. Yeah?
>> I was gonna say is another thing that we're losing too is the ability to kind of. You have these components now that you can't test.
>> Yes. [LAUGH] Yes, so that is true too. And we'll round back into that one as well. Before because they were receiving everything I could pass things in.

[00:07:16] And I could theoretically test them now that they're hooked into this magical context API. They come with a bunch of extra stuff. Now, there's some ways to handle this one. One thing that we do is we basically have a like a test context that we wrap it in for testing, right?

[00:07:32] That is the easiest way. There are also patterns, like the container pattern or the higher order component pattern. Where then you hug the presentational component that doesn't have any access to the context with one that only, this is very similar to what our provider did to the application, which is it did all the state management in the past into a dumb application component.

[00:07:52] We can do the same thing. We have a presentational component, and a container component that does all the state management and pass it in. This is very common in Redux as well as to separate those two. So you have two options. Which is one, make a text context, which we do in a lot of cases.

[00:08:05] Or two, just separate those two out so you can test the presentational piece separate from the actual state management. So, yeah, that's a great point. We also lost some of the Performance optimizations but I would incur you as to like make sure you have a performance problem before you worry about that.

[00:08:21] It is very easy to say in a code reveal I heard that's not as performance but react is fast and if it's not perceptible, it's that trade off of maintainability versus performance and I would argue You know, in a lot of cases like if you can't ship a feature cuz everything is hard, We're all writing softwares for our customers, some times it's a trade-off between what is the right choice for our customers, the ability to ship features or our performance optimization.

[00:08:51] And like some times performance is important I do not want to make it sound like performance is not important but if it's not actually not performant Choosing the unmaintainable thing to fix a non existent performance problem. Like if you're not code splitting, I don't wanna hear about like the context API and like react memo, right?

[00:09:07] If you're not optimizing fonts and images, this is like a high class problem. There are some lower hanging fruits. So it's a decision you need to make So we've got it in there, we've got it with the Grudges. Now, NewGrudge, so what would NewGrudge need? Really, if you look at it now, it's getting in this onSubmit, and onSubmit was really just addGrudge was being passed in, if you remember from the previous version.

[00:09:29] Well, it doesn't need addGrudge passed in. It can just reach into the context and grab it itself. Do you know what you are going to do?You're going to reach into the context API, and you're going to grab out at drudge and get rid of this prop right up here and replace this with the actual edge that you pull in from the garage context.