Toast messages mechanism in React Native using React Context

13 February 2020

Introduction

Toasts are lightweight notifications designed to mimic the push notifications. They have been popularized by mobile and desktop operating systems. They’re used mainly internally, in-app to provide users with some feedback about errors, successfully completed actions, etc. There is plenty of techniques and different implementations, a lot of various packages to choose from. On the other hand, React introduced New Context API with version 16.3, which is quite robust and could be used in state management or even for displaying toasts.

So I’m going to share a cool concept on how to add a notification system to a React Native application using Context API without any third-party packages. Yes, I will be using React Native here, but the concept still applies to plain React for the Web.

Let’s start

Setup

Let’s set up a new project. I will be using a template with TypeScript, so you can see how it could be typed. Your environment should be prepared for React Native. You can look into the official guide.

And then run it. React Native uses Yarn by default.

Simple app

Let’s remove the initial boilerplate code and set up a few simple screens using react-navigation to demonstrate how we can display toasts on no matter which screen. In the docs you can find a well-described Hello React Navigation guide, just follow the steps to set up the bare minimum. In my case, the simple app looks like this.

Demo app screenshot

It has 2 screens: Home and Details, from which we are going to trigger toasts.

Context implementation

Portal Context

Teleport

Then let’s define our Context. It will have gates. They can accept our components somewhere in the tree hierarchy, for the demo there will be only one gate available – toaster. Then a teleport function that can send a component to a gate (a toast to the root component, in our case), and the showToast function for convenience. In general, we can use the teleport function for moving not only toasts through our React hierarchy.

Portal Provider

Next let’s implement the business logic, for these purposes we create Portal Provider. With the the help of if, we can wrap our entire app and the logic will be available throughout the app.

The Provider’s state manages our gates and its components – exactly what we need. Under the hood the teleportfunction sets gate’s state value to a component that we would send.

And finally the showToast function which is just a convenient method for us. It will be using the defined earlier teleportfunction and will send our actual <Toast /> component. There are 2 arguments: one for the message of the toast, the other for its type whether it’s error, info or success, etc. By default it has a generic error.

Portal Consumer

Then let’s move to the Context Consumer. In fact, the Consumer is our Gate. Nothing special here, just a render prop that displays the sent component as children.

Bonus: useToaster hook

One more nice to have thing is a custom hook which we can use for getting the showToast function without repeating ourselves. It’s pretty simple and returns just the Context’s method. The method’s signature is automatically typed! So sweeet!

Enable the feature

Now we implemented everything that was necessary. Let’s enable it for our app!

Providing and Consuming

First wrap the app into ContextProvider. It should be at one level higher than the navigation, so we could see our toasts covering the app’s navigation bar.

Add the Gate for the toasts. It could be at the same level as our navigation – it is enough to display toasts on the navigation bar. Provide the name for the Gate, in this case it would be toaster.

Teleporting

And finally we can use either useToaster, or even contextType (for class components) to trigger the much awaited toasts somewhere in the code. Let’s add them to our screens!

Functional component

Class component

Final touch

One more think left is to automatically clean up our toasts. It’s necessary to clean our gates before sending new toasts since it could cause rendering issues. So don’t forget to call teleport with null in the onEndAnimation callback.

And voilà!

Take a look at the demo. It works on both screens!

Conclusion

In my opinion, this one is pretty amazing way to implement toasts display in the app and in React. Feel free to play with it and maybe you could find it useful for another use case, not only for toasters. The repo with the code is available on my GitHub. Happy teleporting!

Sidenote: I spied the initial idea from Naor Zruk, but then improved it a little bit and adapted for Notification system. Thanks Naor for inspiring me!