Learn the React Context API with a Practical Example You Can Bring to Your Apps
Tags: react, webdev, materialdesign
Published: 2018-06-14 02:00:23

---
title: Learn the React Context API with a Practical Example You Can Bring to Your Apps
published: true
tags: react,web-development,material-design,reactjs
canonical_url: https://medium.com/@shawn.webdev/understanding-the-react-context-api-through-building-a-shared-snackbar-for-in-app-notifications-6c199446b80c
---

![](https://cdn-images-1.medium.com/max/512/1*tDxVH_WUqvu7fiNorh_EfQ.png)

### Preface

Most apps need a way to unobtrusively display notifications to users as they happen. Suppose you're running a 20% off sale and you'd like to let your users know as soon as they sign in, or maybe after they submit feedback you want to display a thank you message.

Material UI provides a snackbar component which is great for these types of messages, so I'll be using that for this example. That being said, this article is much more about the Context API than Material UI, and swapping out Material UI for any other component library would be very simple with this approach.

Many apps need to trigger messages from dozens of different components. The React Context API makes it dead simple to provide all components access to a shared snackbar so they can trigger these messages without needing to implement separate components for each message. Here's how.

### What We’re Building

![](https://cdn-images-1.medium.com/max/364/1*d8iHKTMYovt37-tA1pF4mQ.gif)

### Setup/Dependencies

This post assumes you already have a React app set up with **@material-ui/core 1.0.0+** and **@material-ui/icons 1.0.0+** installed as dependencies.

### Creating the Context

First, we need to create our Context API **provider** and **consumer** components. The **provider** _provides_ the state of our snackbar, as well as some functions for manipulating that state, to all **consumers**. This allows all child components to access and manipulate the **provider** ’s state no matter how deep they are within the component hierarchy. No prop drilling required!

{% gist https://gist.github.com/sreisner/8717875cf11cc83fdac9dd4025af2c25 %}

The first step is creating a context by calling _React.createContext()_. The object returned contains two properties, Provider and Consumer. We use these to build out the components that will manage and interact with the snackbar’s state.

_From here on out, when I use the terms “provider” and “consumer”, I’m referring to the_ **_SharedSnackbarProvider_** _and_ **_SharedSnackbarConsumer_** _components from this section._

As you can see, our provider is a pretty standard component. In its _render_ function, we render a **SharedSnackbarContext.Provider** component with a _value_ prop. The object passed to the _value_ prop is what consumers will be able to access so they can interact with our snackbar. For lack of a better term, this is the **API** for our shared snackbar component.

Take note of the _TODO_ on line 41. Eventually we’ll be rendering the actual snackbar _within_ the context provider’s _render_ function as a sibling to its children. This ensures that when the provider is rendered, all children will be using the same exact snackbar component.

### Creating the Shared Snackbar Component

Now we need to build the presentation component responsible for rendering the snackbar UI based on the state of the provider. This component will use the consumer to access the properties it needs for rendering.

{% gist https://gist.github.com/sreisner/0078c0df07359941e31daff4495c9278 %}

Here we’ve built a component that renders the snackbar UI in a function within the **SharedSnackbarConsumer** component. The argument to the function is the _value_ prop object we exposed from our provider. As a result, when the state of the provider is updated, it will trigger the snackbar component to rerender.

Now we can render this component in our provider’s _render_ function.

{% gist https://gist.github.com/sreisner/a590795afc8b5b681c6dc512ae4e8fb2 %}

### Rendering the Provider

At this point, we’re almost finished with the infrastructure. There’s just one last thing to do, which is to render the provider within our app. I’m going to place the provider at the root of the entire app so that all children have access to the snackbar.

{% gist https://gist.github.com/sreisner/5043d2a60a554d88a86f92cb2e857c93 %}

### Opening the Snackbar from Child Components

Now, **ButtonA** and **ButtonB** can render their UI and trigger in-app messages without needing to directly receive props from the root of the app! 🤙

{% gist https://gist.github.com/sreisner/87c0a631de97561d76a98bb02740f6fb %}

### Summary

In summary, here’s what happening.

1. First, we created a **context provider** component which manages the global state for our snackbar.
2. We then created a component that renders the snackbar’s UI based on the state of the provider. This component subscribes to the provider state in its render function via a **context consumer**.
3. Finally, we rendered two buttons that update the state of the **context provider** with the _openSnackbar_ function, which was passed to them via a **context consumer**. This results in the changes propagating down to the snackbar component, triggering a re-render.

Material UI provides a number of other snackbar features I did not implement with this example, such as action buttons and color customization. For the sake of simplicity I didn’t add the ability to customize those features. Adding that logic yourself would be a great next step if you’re really looking to learn the Context API!

Thank you so much for taking the time to improve yourself. If you found this article useful in any way, I will always accept a clap or two. While you’re at it, take a few seconds and follow me for more great content:

- [A Quick, Practical Use Case for ES6 Generators: Building an Infinitely Repeating Array](https://dev.to/sreisner/a-quick-practical-use-case-for-es6-generators-building-an-infinitely-repeating-array-1onk)
- [Building a “Mask Toggle” Password Input Component w/ React and Material UI](https://dev.to/sreisner/building-a-mask-toggle-password-input-component-w-react-and-material-ui-37m3)

**Twitter** : [@ReisnerShawn](https://twitter.com/ReisnerShawn)  
**dev.to** : [@sreisner](https://dev.to/sreisner)  
**Instagram** : [@shawn.webdev](https://www.instagram.com/shawn.webdev)

Happy coding!