DEV Community

Kit Lung
Kit Lung

Posted on • Updated on

Creating a message component for displaying error in ReactJS

Today I would like to share my way of displaying error or custom messages in React.
The idea is to use context and custom hook so we are able to access the component on all pages.

Custom Message Context Provider

Let's create a context provider first.

// CustomMessageProvider.tsx

import { createContext, useState } from 'react';

* show : whether show or hide the message block
* type : what theme is the message block
* msg : message displaying on the message block
* You can add more field if you want
interface Msg {
  show: boolean;
  type: 'error' | 'info' | 'success' | 'warning';
  msg: string;

const defaultMsg = {
    show: false,
    type: 'success',
    msg: ''
} as Msg

export const CustomMessageContext = createContext({
    msg: defaultMsg as Msg,
    setMsg: (_: Msg) => {}

export const CustomMessageProvider = ({children}) => {
    const [msgState, setMsgState] = useState(defaultMsg)

// CustomMessageContext contains an object 
// and also a method for setState

    const contextValue = {
        msg: msgState,
        setMsg: (val: Msg) => setMsgState(val)
    return (
        <CustomMessageContext.Provider value={contextValue}>
Enter fullscreen mode Exit fullscreen mode

Custom Snackbar

After that, create a custom snackbar using material-ui

// CustomSnackBar.tsx
const CustomSnackBar = () => {
    const { msg, setMsg } = useMsg();
    return (
          onClose={() => {
                  show: false,
                  type: msg.type, 
                  msg: '' 
          <Alert severity={msg.type}>{msg.msg}</Alert>

const Alert = (props) => {
    return (

export default CustomSnackBar;
Enter fullscreen mode Exit fullscreen mode

Then we can add the provider to App.tsx so that we can access the context on all pages.

// App.tsx
const App = () => {
        <CustomSnackBar />
export default App
Enter fullscreen mode Exit fullscreen mode


Custom hook

What we are going to do now is to add a custom hook so we don't have to call useContext in all pages

// customMessageHook.tsx
const useMsg = () => {
    const { msg, setMsg } = useContext(CustomMessageContext);
    return { msg, setMsg };
export default useMsg;
Enter fullscreen mode Exit fullscreen mode


We can now call useMsg on all pages.
Let say you want to display an error if the fetch API failed on a page.

const { setMsg } = useMsg();


const fetchApi = async () => {
    try {
    } catch (err) {
            show: true, 
            type: 'error',
            msg: 'Oops, error'
Enter fullscreen mode Exit fullscreen mode

Alt Text


I know there are some more elegant ways to implement this, feel free to leave me a comment and share what you think.
Have a nice day.

Top comments (3)

hey_yogini profile image
Yogini Bende

This is a really nice pattern! Very useful one.

t_pk_cd4c946778aa7e14a74e profile image
t pk

Nice one

0xldev profile image

Very helpful