DEV Community

Mohammad Faisal
Mohammad Faisal

Posted on • Edited on • Originally published at mohammadfaisal.dev

Developing a Powerful Alert System Using React Context API

To read more articles like this, visit my blog

React context API has supercharged our React applications. Now we can do stuff with pure React without any help from other libraries like Redux which was not possible before.

Today I am going to share how I used Context in a large-scale application.

We will build an alert system. Whenever any user clicks a button or user needs to see some information in a modal we will use Context to condense the logic inside one component.

Let’s begin…

Overview:

The main process will be something like this

  • We will create a context with a reducer.

  • We wrap the whole component with that context

  • Then from any component, we will trigger an action to update the value of the context

  • An alert component will consume the context, thus avoiding unnecessary re-render.

  • Whenever any update happens in the context, the Alert component will be triggered.

STEP 1: Lets Alert Types

Let’s first define what kind of alerts we will be dealing with here. Create a file named AlertTypes.ts . And put the following code there.

export enum AlertTypes {
    SUCCESS= 'success',
    ERROR = 'error',
    WARNING = 'warning',
    INFO = 'info',
    NONE =' none'
}
Enter fullscreen mode Exit fullscreen mode

Step 2: Alert Action

Now create an action file. We could create a single file with all the actions and reducers, but this is cleaner.

import { AlertTypes } from '../../types/AlertTypes'

export default class AlertAction {
    static SHOW_ALERT = 'SHOW_ALERT'

    static showSuccessAlert = (message) => {
        return {
            type: AlertAction.SHOW_ALERT,
            payload: { message, type: AlertTypes.SUCCESS }
        }
    }

    static showErrorAlert = (message) => {
        return {
            type: AlertAction.SHOW_ALERT,
            payload: { message, type: AlertTypes.ERROR }
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

In this file, we have added 2 actions for now. Our showSuccessAlert() function takes a single parameter as a message. This is the message that we will be showing to the users.

Step 3: Alert Reducer

Now we will create our reducer file. Our alert reducer is a simple function that checks the action type and sets the value of our state value.

import AlertAction from '../alert/AlertAction'

const AlertReducer = (state: any, action: any) => {
    switch (action.type) {
        case AlertAction.SHOW_ALERT:
            return {
                ...state,
                alertShower: action.payload
            }
        default:
            return state
    }
}

export default AlertReducer
Enter fullscreen mode Exit fullscreen mode

Step 4: Alert Store

Now it’s time to create our store. We will be using the useReducer hook of React. Our state has only 1 variable named alertShower . This variable will hold the type and message of the alert.

import { createContext, useReducer } from 'react'
import { AlertTypes } from '../../types/AlertTypes'
import reducer from './GlobalReducer'

interface IAlertShower {
    type: AlertTypes
    message: string
}

interface IAlertState {
    alertShower?: IAlertShower
}

const initialState: IAlertState = {
    alertShower: {
        type: AlertTypes.NONE,
        message: ''
    }
}

export const AlertContext = createContext<any>(initialState)

export const AlertProvider = ({ children }) => {
    const [state, dispatch] = useReducer(reducer, initialState)

    const value: any = [state, dispatch]

    return <AlertContext.Provider value={value}>{children}</AlertContext.Provider>
}
Enter fullscreen mode Exit fullscreen mode

Step 5: Wrap Component

Now we need to wrap our app with this context because alerts can be triggered from anywhere.

import React from 'react'
import { AlertProvider } from '../AlertProvider'
import AlertPopup from './general-components/AlertPopup'

function App() {
    return (
        <AlertProvider>
            <div className='App'>
                <AlertPopup />
                <AnyComponent />
            </div>
        </AlertProvider>
    )
}

export default App
Enter fullscreen mode Exit fullscreen mode

Notice how we have included a special component named AlertPopup . This will be our Alert component. We need this to be global as there will be only one alert component in the whole application.

Step 6: Alert Component

We are using Material-UI dialog for acting as our alert. You can use any design library or even use your own.

We don’t have to include this component over and over in all the places where we need to show the user some message.

import { Card, CardContent } from '@material-ui/core'
import Dialog from '@material-ui/core/Dialog'
import { Alert, AlertTitle } from '@material-ui/lab'
import React, { useContext, useEffect, useState } from 'react'
import { AlertContext } from './AlertContext'
import { AlertTypes } from '../types/AlertTypes'

export default function AlertPopup() {
    const [state, dispatch] = useContext(AlertContext)

    const [open, setOpen] = useState(false)
    const [alertType, setAlertType] = useState<AlertTypes>(AlertTypes.NONE)
    const [message, setMessage] = useState<string>('Some Message')

    useEffect(() => {
        const { message, type } = state.alertShower
        setAlertType(type)
        setMessage(message)
        if (type !== AlertTypes.NONE) setOpen(true)
    }, [state.alertShower])

    const handleClose = () => setOpen(false)
    return (
        <Dialog open={open} onClose={handleClose} aria-labelledby='max-width-dialog-title'>
            <Card variant='outlined'>
                <CardContent>
                    <Alert severity={alertType}>
                        <AlertTitle>{message}</AlertTitle>
                    </Alert>
                </CardContent>
            </Card>
        </Dialog>
    )
}
Enter fullscreen mode Exit fullscreen mode

Step 7: Use the Alert

Now we need to test what we have created for ourselves. Create a button named AlertButton.tsx . Place this component anywhere you want.

This button will dispatch an action that will update the value of the alert context, which in turn triggers our alert component.

import React, { useContext } from 'react'
import AlertAction from '../../data/alert/AlertAction'
import { AlertContext } from './AlertStore'

export default function AlertButton() {
    const [state, dispatch] = useContext(AlertContext)

    const showAlert = () => dispatch(AlertAction.showErrorAlert('An Error Occurred'))
    return <button onClick={showAlert}> Show Alert </button>
}
Enter fullscreen mode Exit fullscreen mode

How awesome is that?

Food for thought

So, what will you do if you need to add some action to this alert modal? Can you do that?

Conclusion

This article is a practical guide on using React’s Context API to build real-life applications.

Almost all applications will need some feedback mechanism. I hope this can help. Let me know if you didn’t understand anything.

Have something to say? Get in touch with me via LinkedIn or Personal Website

Top comments (0)