If you already have a subscription, you can sign in.
Enjoy free content straight from your inbox 💌
00:00
In this lesson, not only will we look at the API provider by React context, but also look at why you would want to use context, the benefits it provides, and some best practices when using context. So let's go to demonstrate the need for context. Consider a simple themed button component for the button props we have on click and children along with the theme, which can be light or dark. Then we have some base styles, some styles for the light mode and some styles for the dark mode. Beyond toggling the styles based on the props theme, our button component is going to be pretty simple.
00:35
It simply takes the props and renders out a native button. Now let's try to use this button in our application. Within our app dsx, we bring in the button component and then we create some state to manage the light versus dark mode using a simple use state along with the toggle theme neutrality function, which toggles the theme between light and dark. To toggle the theme between light and dark, we create a simple native button which displays the sun or the moon depending upon the current theme. And with this theme state management out of the way,
01:08
let's use our themed button component and note that every single time we have to use a button component, we have to pass in the current theme because that is what it accepts as props. Of course, if you run an application, it does function the way you would expect. We can toggle between light and dark and because the theme variable changes the buttons update the display to be light mode or dark mode. And of course the buttons have the remaining functionality as well like click and displaying the children. And the thing that we want to focus in on is that we have to pass in the theme again
01:40
and again every single time we want to use a button. This might not seem like a big deal right now, but if we use this button in any other component, for example, we create a custom form component, then the form component needs to take the theme as well because that is what it needs to pass to the button that it's going to create. Which means whenever we use the form component, we again have to pass the theme and this just starts to become a bit cumbersome. This is exactly the kind of problem that the context API is designed to solve. It allows a portion of our app to get access to a variable managed by react without having to pass it
02:13
around again and again through props. So let's get rid of the theme prop from our button component and we will come up with some magical way of passing the theme down without having to use props. For now, we create a local temporary variable and use that to toggle our styles. Now that the button component doesn't take the theme prop, you can see how much easier it is to use the button component as well as other components that might depend on it. For example, the form component. Now the magical task of taking a value and passing it through to children without having to pass it
02:46
through props is what is offered by context. We can create a context within React by using a function called Create context, which we import from React and then passing it an initial value to get back A context object. Additionally, the create context function takes in a generic argument where we can pass in the type. And here we are saying that the context can either be the string literal light or the string literal dark. Now this context object that is returned from create context, which we have exported as theme context, has a member called provider which can be used to provide the value for the context.
03:22
Let's bring in theme context within our app component and create this new component app with theme which uses use state to manage a theme variable the same way we did before, and then also has the utility double theme function and then renders that button that we used to toggle the theme. But the more important thing over here is that it also uses theme context provider to provide the value for the current theme. Providing the theme value using theme context or provider over here means that any of its children including app or apps, children like those buttons can actually read this
03:56
value using theme context. So let's jump into our button component and bring in the theme context from our theme module Minority. Use the value from the context. We need to use a hook that is provided by React called Use Context. And with these two imports in place, our theme context and the use context utility from React, we can use use context to pass in the theme context to get the value from the context which we store in a variable called theme. And that's it. We have the same application functioning where we can toggle between light and dark mode
04:30
and the buttons automatically update, but this time without using props and instead using Use context. Not that the context API isn't particularly complicated. We still have the same application logic that we had before we have that themeing button. If we have our app component containing the buttons in the form. The only difference is that now we have this theme context which is used to provide a value and consume it on the other side. Now that we understand the basics of create context, providing a value with context provider and consuming it with use context with a real world example,
05:03
let's simplify it further to look at its pay bones API. So let's get rid of this Use state logic for the theme and this button that is used for the theme. Because honestly, the context is for any value that you want to pass around, not necessarily just for state, it can be as simple as reading a config file or any value that you want to pass in. So let's just hard code the value of light and you can see that the application functions and if you just change this value to dark, you can see that that is the value that gets passed down to the buttons.
05:36
In addition to themes, you can think of other things that you might want to pass in. For example, a global language specification or the current user region. In additional benefit of using context is that it provides fine grain control over a value that is only available over a particular portion of the React render tree. As an example, even though we have the UI currently Rendering with dark mode, we can actually wrap the form with its own theme context provider and provide a different value. For example, light. Now the form component and its children, which is just a button,
06:09
will get this updated value. And you can see that alpha and beta have the dark mode, whereas the form submit has light mode because of this nested provider. A use case for nested providers is using context for spacing and then providing a different default spacing value for a particular portion of your ui. A question that you might have is what happens if you use context in a component when there is no parent provider present? So let's get rid of all of the provider components within our application. We do not wrap the app, we do not wrap the form. And you might think that the application is going to crash,
06:43
but you can see that it still functions fine. So the question is, if there is no provider, then how come the button component is still getting the theme light? And the answer to this mystery lies within the theme context. When we created the theme context, we had to provide a default value and we just chose the default value to be light. And that is the value that the context returns. If there is no parent provider, if we change this to dark, you can see that the default has changed and therefore the buttons are now rendering dark mode. Most of the time you will be utilizing the use context hook,
07:18
but since hooks aren't supported in class components, react does allow you to get access to the value of the context in the render portion of your component by using the context consumer component. So within our component, instead of using the use context hook, let's wrap our button, which uses the theme with the theme context, consumer component. This component actually takes a child, which must be a function, which is what type strip is complaining. So let's convert this into a function. And this function will get past the current value from the context which we store in a variable called theme the same
07:54
way we were doing before. And now the application should function and indeed it does. We can change the value on the context, and this is read by theme context dot consumer and pass down to the child function. Now, even though this is functionally exactly the same as the use context hook, I don't think anybody will argue that the use context version is much cleaner. So unless you are using class components, and again, I recommend that you do not use class components, you should be using function components. With the use context hook, it is quite a common pattern to create a utility module that makes it easier
08:28
to provide a value and use the value from a particular context. So from a theme module, instead of exporting theme context, which is a bit of a raw object, let's create some better abstractions. On top of this for our consumers, we will create a custom hook called use theme within which we will simply use react, use context to get the value from the theme context and return that. And similarly for our providers, instead of forcing Them to use theme context or provider, let's just create a new variable which we export called Theme provider, which is simply going to point
09:02
to theme context provider. With these utilities, our consumers don't need to use context and pass in the theme context, and our providers will have a more ergonomic name of theme provider where they provide the value. So within our button component, we get rid of the theme context and the use context and the call to use context passing in the theme context and just bring in the use theme custom hook. And we use this custom hook and get the theme value, which we can use within the button. And similarly for the provider side, our import is going to look simple as well. It's going to be theme provider and we use it
09:36
whenever we want to, for example, wrap our entire application with a theme provider providing a theme value of as an example light. And that is it. Our application is now going to be in light mode, and if we change the value to dark, our application swaps over to dark mode. So if you are ever looking for a cheat sheet on how to use React context, I think this module by itself is a pretty neat example. I'll wrap things up there. As always, thank you for joining me and I will see you in the next one in.