Avoid passing props deeply by using React Context

Dave Ceddia
InstructorDave Ceddia
Share this video with your friends

Social Share Links

Send Tweet

Passing data deep through a React app usually involves tedious passing of props or a complex solution like Redux. Here you’ll learn how to simplify an app that’s currently passing data with props by refactoring it to use React’s Context API.

Instructor: [00:00] We're looking at the route component of the app right now. It's rendering this login page because the current user is null right now. If I log in, the login page is going to call its onLogin prop. Then it'll put that into state and rerender the main page, which is what we're seeing here now.

[00:17] The current user is passed down to main page, which in turn passes it down to two more components without using it. It's passing it to header, which passes it down to user menu, which is this over here. Back to main page, we also see that current user is being passed to message list, which displays this personalized message over here.

[00:37] This works OK, but we have to pass current user through a bunch of components that don't care about it. Like main page doesn't actually use it. It just receives it and passes it along. Same with header.

[00:48] One way we can clean this up is using React Context. We can create a new context. I'm going to do that in a separate file called UserContext.js. In here, we'll import React and use React.createContext to create a new context.

[01:04] It takes a default value, but if we pass nothing, it'll just start off undefined. It returns an object, that we'll just call Context, with two properties. This has a Context.Consumer and a Context.Provider. We're just going to export default this whole Context object.

[01:23] If we go back over to index, we can import UserContext. We'll wrap the main page component with the UserContext.Provider. The provider takes a value prop, which is the value that it's going to pass down through this tree here. We're going to pass this state current user.

[01:42] Now let's drill down to where this context is used. We can use the new Context.Consumer to get that value out. Let's import our UserContext. Then we can wrap this message list with a UserContext.Consumer.

[01:58] If we try this right now, we're going to get an error because the consumer expects you to pass a single function as a child and we're passing an actual element here. What we want to do is wrap this element in a function. This function receives the value that we passed in from the provider.

[02:15] Here we passed a value prop. The value comes out as the first argument of this function. You can call it whatever you want. You can call it value. You can call it user and then use that user down here. Then we don't need a current user of prop anymore. You can see the message still renders out.

[02:32] Now we'll go over to the header, which is accepting the current user prop and passing it along, but it's not actually using that prop. If we drill into user menu, this is where we are actually using it, down here.

[02:44] Let's import that UserContext. Then we can wrap this component in UserContext.Consumer. Then we just need to wrap the content in a function which will receive the user. Then we can use user instead of props current user.

[03:04] Now we can go through and get rid of the current user prop everywhere it's no longer needed. Let's start up at index. We're passing current user to main page. We don't need to do that anymore. In main page, we were passing it along to header and message list. We can get rid of it here and from header and from message list.

[03:27] In message list, we already got rid of it. Header, we could remove the prop from here. We don't need to pass it to user menu. We already took care of user menu. If we save index, we can see the app is still working, but we don't have to pass the current user manually through all these levels anymore.