Create a Global Notification Component with React and Context! Part 1 (with code)

Albert Kim
8 min readMay 7, 2019

--

The functionality you will learn how to implement in this tutorial.

Part 2 here:

Are you looking to take your UI/UX development skills to the next level?

Do you want to learn how to use the React Context in a realistic scenario?

Or do you want to learn how to create this epic UI/UX interaction?

Having a component in your app dedicated to displaying messages to your user is a great way to improve the UX for the user.

If your user is performing an action, it can be unclear whether or not that action was successful, for example, creating a user account, or deleting an item. It can be useful to have something as simple as flashing a message in the middle of the screen to update your user about what happened.

In this article you will learn how to implement this kind of functionality using only React and Context.

Table of contents:

This post:

Step 1: Project set up

  • Create react app
  • React router dom
  • Bulma

Step 2: Create the notification component

  • Getting the component rendered on the screen
  • Where to place this component in your app hierarchy
  • The CSS properties needed

Next post:

Step 3: Setting up the Context Provider

  • Create context
  • Create provider
  • Add context provider to the project

Step 4: Adding the functionality to the components

  • Updating the context state

Step 1: Project set up

Link to the repo for step 1:

To start we are going to be using the create react app project as the base for our React app. You can create a new react project by typing:

npx create-react-app your-project-name

The repo for create react app is here :

When you type “npx create-react-app your-project-name” on your command line what that will do is create a new folder, inside of your current folder, and make a new project called your-project-name.

If you are already in the folder you want to have your react app in, then you can type the command:

npx create-react-app .

What the “.” Does is indicate that you want to create the react app inside the current folder which you are typing the command.

Once the create react app is finished initializing, you should have a standard create react project that you can run with

npm start

Or

yarn start

Delete some files

You don’t need all the files that the project comes with. You can delete App.css, App.test.js index.css, and logo.svg

Update the files that were importing the files you just deleted.

At this point your project should look like the master branch in this repo:

I only have App.js, and index.js and in App.js I just have a paragraph tag with “Hello world” in it.

Adding react router dom and Bulma

In this project we are going to have 2 pages, the index page (with a component called Main.js) and a profile page (with a component called Profile.js).

To get things going, let’s get a hello world printed on 2 new components we will make called Main.js and Profile.js.

But first since we need to handle routing in this project let’s add a new dependency called “react-router-dom” to handle the routing. And while we’re adding new dependencies let’s also add “Bulma” which is a light weight css framework that I am a fan of.

Run the command

yarn add react-router-dom bulma

Or the npm equivalent.

Now let’s add these new dependencies in our project.

If you add a css module like bulma or bootstrap or materialize to your project, how you import it is just by adding the files you want to a top level component in your react app.

If you open the node_modules folder and find bulma, you’ll see that it’s like any other node project with a package.json and other files.

But we only care about the css file that it comes with.

There is a css folder and in that we want the “bulma.min.css” file.

Importing this css file is very simple, you just type:

import "bulma/css/bulma.min.css";

So in your App.js file (the highest level component which will serve as the main entry point for all the other components) add that line and all of the components contained in App.js will be able to use bulma classes.

Now let’s add routing.

For the react-router-dom package we will only be using 2 components to add routing to the App.js file.

Add the line:

import { BrowserRouter as Router, Route } from "react-router-dom";

To your App.js file.

App.js will now serve as the place where the routes will lie. To do this we want to have the top level component that gets returned from App.js to be the Router component, and in that we will add the routes.

App.js should now look like this:

<Router>  <Route path="/" exact component={Main} />  <Route path="/profile" component={Profile} /></Router>

What the Route component is doing is telling the React app how to render pages. Since users expect websites to work based on what url they’re visiting, it makes sense to structure your React app in that way.

When users visit the “/” route which is the entry point to your website, show the Main component. The exact prop is added because if you don’t add that, then “/profile” also counts as “/” because “/profile” contains “/”. We only want to show the Main component when users are only on “/” which is why the exact keyword is added.

When they go to the /profile route, then show the Profile component.

Now let’s create those components:

In the src folder create 2 new components, Main.js and Profile.js

Make these functional components which just print “Hello world”

Import these new components into your App.js file and this should make your app run.

Now let’s add very minimal styling to this project so that it doesn’t look amateur.

Since we are using Bulma we only need to add the class names we want on what elements.

We also want to add buttons, one to show the notification, and one to switch pages.

So the html layout of Main.js and Profile.js would look something like a div containing a text element and two buttons.

Since the div is a section within this web app, let’s add the section class from bulma to this element.

Since the text element is a title, let’s add the title class from bulma to that element.

Since the button is a button and we want it to look decent with minimal effort let’s add the button class to the button.

We also want to be able to switch to the other page inside each component so we need the Link component from react-router-dom which will add navigation ability to our components.

Link is imported like:

import { Link } from “react-router-dom”;

Now your main/profile component should look something like this:

<div className="section">  <p className="title">Hello from main.js</p>  <button className="button">Show notification</button>  <Link className="button" to="/profile">    Profile  </Link></div>

Now your code should be similar to the step-one branch in this repo

It should also look like this:

The app at the end of step 1

Recap

  • Created react app
  • Deleted extra files
  • Added react-router-dom and bulma and added it to the project
  • Created routes
  • Added some bulma styling to the components

Step 2: Create the notification component

Next we will create the component that is the notification. This will be a functional component that has special css properties which allow it to act like a global message that is displayed in front of anything happening in your app.

Those css properties are: position and z-index. The position property allows an html element to be “positioned” in different ways. The position we want our notification component to be is “fixed.”

(In the repo the position is “absolute” but that should be “fixed”)

A fixed positioned element is positioned on the page relative to the viewport, and not its parent element.

That means a div with a position of fixed is not within the normal hierarchy of elements, it’s “outside” of it and positioned based on the screen.

We need the component to have this property because we want the notification to appear in the middle of the screen, no matter what component activates it and show it in front of everything.

The z index property allows the element to appear on top of those with a lower z index. If html elements are stacked like pieces of paper, then you see the top level paper and every other piece of paper under it is invisible unless it’s outside of the width and height of the higher level piece of paper.

The higher the z index value, the higher in the stack the element will be.

We will also add a notification class to an inner div in that component which is a class from Bulma. It styles the div in a way that makes it look like a notification. We will also be adding modifiers later to change the color depending on the status of the notification.

For now the component should look like this:

const FlashMessage = (props) => {  if (props.show) {    return (      <div        style={{          position: "absolute",          zIndex: 500,          left: "50%",          top: "50%",          transform: "translate(-50%, -50%)",          boxShadow: "4px 4px 10px -4px rgba(0,0,0,0.58)"        }}    >      <div className={`notification`}>        <p>flash message</p>      </div>    </div>  );  } else {    return null;  }};

The basic idea of this component is that it will take in some props and if the show prop is true, we will return the html, if it is not true then we will return null.

We need this because if we are always returning html then the notification component will always show. We don’t want this notification to always show, only show when it is relevant, and otherwise return null.

Where do we place this app in the project?

We don’t want it nested in a component like Main or Profile because every page needs to be able to render this component.

So we put it in the App.js file alongside the routes.

<Router>   
<Route path="/" exact component={Main} />
<Route path="/profile" component={Profile} />
<FlashMessage show={true} />
</Router>

Since FlashMessage is in the same position as the routes, it will be displayed no matter what page is rendered because it’s in the same hierarchy as the routes.

More about the author

If you liked what you read, please consider following me on Twitter!

I plan on writing more often and I will definitely tweet about it when I do.

I also have other stories on my Medium profile page for you to check out!

--

--

Albert Kim

Helping freelance writers build their business with a website builder designed for their needs at https://leavewithaweb.site