Join egghead, unlock knowledge.

Want more egghead?

This lesson is for members. Join us? Get access to all 3,000+ tutorials + a community with expert developers around the world.

Unlock This Lesson
Become a member
to unlock all features

Level Up!

Access all courses & lessons on egghead today and lock-in your price for life.


    Hide the Implementation Details of a Context Provider


    A single Root component responsible for disparate data like current user, language setting, and theme will become messy and hard to work with. One way to fix this is to move related logic and data into a class, along with a Context Provider to get the data out. In this lesson we’ll group the logic and data for login, and use Context to pass it throughout the app.



    Become a Member to view code

    You must be a Pro Member to view code

    Access all courses and lessons, track your progress, gain confidence and expertise.

    Become a Member
    and unlock code for this lesson
    orLog In




    Instructor: Right now, the root component holds the current user and the functions to update it, and it passes it around with this provider. Let's see how we can centralize the user state functions and the provider all in one place.

    For that, we're going to use our existing user context file. We'll create a new class here called userProvider. It's going to any render out the provider, which we'll destructure from context. We'll pull that provider and consumer.

    Inside the provider, we're just going to render this.props.children, so anything inside userProvider will get rendered out here. We'll go back over to root and move some of this stuff over. We'll move over the value that we're passing to the context.

    Then we'll also move over the functions and the data. Lastly, we want to move over this fakeUser constant. Then we need to change how this context is exported. Instead of doing one default export, we're going to export userProvider and consumer as userConsumer.

    When we save, we're going to get this error, because of all the places that expect a default export. Let's go update those. We'll start with the root component. Instead of importing userContext, we'll import userProvider and userConsumer. Instead of userContextProvider, we can now use userProvider.

    Since root doesn't have the current user in state anymore, we also need a userConsumer to get access to that user. We'll use the renderProps pattern to pull out the user from the context object, and then use that user here.

    That fixes this page, and now, login page is broken. Let's open up login page. We can replace userContext with userConsumer. Down below, instead of userContextConsumer, we'll update this to be userConsumer.

    Now, we can move onto the messageList file. We'll replace userContext with userConsumer, userContextConsumer with userConsumer. The last problem is in userMenu. We'll open that up and do the same thing here, replacing this with userConsumer and the usage with userConsumer.

    Now, the app is back to working again, and you can see the context is being used here and here. If we log out, we can log back in. Now, we have this one class that holds all of the concerns for users, and the root component doesn't need to worry about that anymore.

    At this point, since the class is stateless, we could turn it into a function component by just cutting and pasting the code from render into the function and deleting the class. We could also move this userProvider, and put it at the top level.

    It's up to you which way you want to write it. This way might be a little bit easier for refactoring later.