Always Use a Custom Hook for Context API, Not useContext (React Context API, TypeScript)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
one of the biggest mistakes that Junior react developers make is not using a custom Hook when they're using the context API let me show you why we want to use a custom hook let's say we have some logo components and if the user has set the theme to dark mode we want to return the dark mode version of this logo otherwise we want to return the light mode version so in this component we need to know the theme and you can imagine in other components we also need to know the theme and we don't want to do all that prop drilling so instead we're going to create a context for the theme the theme is a very typical use case for the context API in react and the proper way to implement it is like this so typically you're going to have a separate folder with all your contacts you can create a contact like this create context and the initial value that you pass here is actually the value that you will get if you try consuming the context outside the provider component so we can create a context like here and then you can use that variable to say dot provider and then you specify the value that you want to pass to the consumers of this context right so we're going to consume this context in the logo and we decide here what we are actually passing through what's going to be an object with theme and set theme so the actual theme is what we're keeping track of here initially it's going to be light so now that we've created our contacts now we need to wrap the part of our app that needs access to this context so I'm using next to S and in XTS we have this layout file this root layout is basically the root component of your whole react component tree so this is wrapping all the pages now with the theme you want to have this pretty high up in your react component 3 because a lot of components need access to it so we might as well just wrap essentially our whole app with it so here we can say theme context provider imported like this and just wrap everything in here and so the children here is going to be the page so it's going to be home page about page next to us we'll just substitute the children here essentially for whatever page you're on so every page now has access to this provider component when I do this I get an issue because we are using use State here which is only possible in client components so let me quickly convert this to a client's component I will save here now the error is gone a very typical mistake here by the way is that people think that now because I made this provider components a clients component some people think that now everything here becomes a client component and that's not true because what we're doing here is just getting the children and just passing through so this can be a client's component and everything in here can stay a server component as for this is the right way of implementing the context API in xjs so now every page has access to the contacts and let's say we want to use it in logo here we need to make sure that logo is part of some page in xjs so here in the root of the app directory you also get the page file here this is for your home page let's just add the logo components here to the home page just so we can then consume the context API and let me input this so I input this now we can consume the context API in this logo and so first part of context API provide the value now you can consume the value so we want to consume that context we can use react use contacts to use context hook now I don't like to import it like that I like to import the function separately like this and then react wants to know which contacts because you can have many different contexts well we call this context the theme context and if we want to use it elsewhere in a different file we need to export that so then here we can go here and we you can say we want to use the theme context and import it like that and get an error here because I'm using a client-side hook so this also needs to become a client component now so the first problem with use context here is that we need to carry around this variable here in every component that we want to use this theme context we have to carry around this theme context here import it specified manually and that's annoying second problem with what we're doing here now let's say we actually want to use the contacts so we have the theme we have we're passing through the theme and set theme so we should be able to use context.theme but if you do that you're going to get an issue now typically you actually just destructure it immediately so we can also just say theme and set theme right this is what we want to get from our context we're consuming our contacts like this usually but this doesn't work out of the box we actually get an issue here because it's saying something about that theme does not exist on type null and the same for set theme and this is coming from the fact that we have specified null here as the value that you should get if you try to consume the context outside the provider component so here here if I would add the logo like this the logo is outside the context provider and here we have specified that the value for context should then be null right so here when I try to consume the context well technically it could be no these logo components could be an instance where we are actually using it outside the profiler component right so let me do this so here you cannot just start using theme and set theme you have to first check that it's not null so if this context is null we want to let's say throw an error so we can immediately solve this we can say theme context should be used theme context provider right and then we can start using the theme and set theme safely so problem one we're just using the context like this is you have to carry around this variable which is annoying second problem is you have to check for that null value every time before you can use it so the solution for this is actually a custom hook so what I do is whenever I create a contacts in the same file here I also create a custom hook for consuming the contacts let's call that function use theme context the function name starts with use because I'm going to use a react hook in there the convention is then that you put the use word in front of the functions so that it's clear that you're using a react hook in there so then here we're not going to do this null check like this OR carry around the variable like this we can already do that here in our reusable function here so here we can simply try to consume that context and I actually get a great suggestion here from Code Pilot so I'm just accept here I don't want to use it like that I will just import it like this here I'm already using the variable so then we get our context we don't want to check for undefined alone we just want to do it like this and if it is in the no we can say used in context must be used within a theme context provider if you try using it outside like here an error will be thrown so you can immediately fix that otherwise we can just return the contacts so if we save this and now we want to consume it in some component we can just use that hook so now we can immediately destructure it and we can just use our custom hook use theme context and I need to import this of course but I'm not exporting it here so let me export this and then let me import this and now we can get rid of this other stuff so let me remove this so now you can see we don't have to carry around some annoying variable every time and we also don't have to check for null value and it's also immediately clear from this hook name what context we are using the problems are now abstracted away into a custom hook now I'm using touch cut here and I haven't properly typed everything here because I didn't want to focus on that in this video but let me quickly do that here just for completeness sake let's just follow the Reds quickly lines so here I have children to type component props I like to separate it out into a separate type and then I'll just type that at the top of the file so there will just be an object with children react node second rescue line here is for Value it's saying something about value is not assignable to type null so what we're doing here is we're saying the values should be in objects with a theme and set theme but we have specified this null value when we created the context and typescript has inferred from that that this context is going to be some null value so then when we try to pass an object it's telling us hey what are you doing you're trying to assign something that should be no value so here when we create the context we need to properly specify what this context shape is going to be let's just call that type of theme context which we can then specify here and this context will be an object with theme that says string and then also set theme which will be a react Setter function here now we don't know the type of the topper hat and I get a great suggestion here from copilot which is actually true in this case but let's say I'm not using compilers or copilot gives a different suggestion you can just hover the set theme typescript will tell you what type this is so let me just accept this now we got vertical line under null because now we're telling typescripts this context is going to be of type theme context which has a theme and set theme and suddenly we're passing null here so it's telling us why you're passing no here this is not in the type that you just specified here so what we can do here is we can say this is going to be of type theme context or null because it could be null if we try to use it outside that context provider in that case it's going to be no otherwise it will be this theme context now we can be a little bit more specific about this theme it's not going to be of any string we can be more specific than that it's going to specifically be only dark or light light so not any string alright so then we get the next Red Square design which is here type string is not assignable to type dark or light so now the problem is we are trying to use a theme in our value here and it thinks that theme can be any string here we have just specified it's going to be either dark or light but this theme variable here has been typed as string so typescript has inferred from this string here that this is going to be of any string right this is a very tricky one so here with you state we can also specify what type it's going to be so we can say that's going to be either dark or light when we do that you can see the rest quickly line here is removed and now we are duplicating ourselves so we could also extract this out into its own type we can just call that type theme and this is going to be this Union type right so here we can just specify the theme separately like this and then we can just use that type here and also here and as a side note by the way this is also one of the reasons why we want to use the type Alias and not interface with interface you cannot assign a union type like this I would interface you're always describing an object with type alien is you can describe an object but then also everything else so in this case the union time alright so then we have one more respiratory line here let's take a look and this is coming from here so here we're basically allowing any string to be passed in when we call the setter function well we can be more specific than that we can now say you can only pass in something that's of type theme so either the string dark or the string lights so now when we do this all of our red Squiggy lines are gone and we solve that whole typescript issue we talk a lot about typescript in my react and next.js course as well in any case make sure you've mastered the fundamentals about JavaScript as well as CSS check out the links in the description thanks for watching and I hope to see the next one
Info
Channel: ByteGrad
Views: 117,668
Rating: undefined out of 5
Keywords:
Id: I7dwJxGuGYQ
Channel Id: undefined
Length: 9min 34sec (574 seconds)
Published: Tue Aug 08 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.