Imagine an app without notifications. Bad user experience, right? How will the user know if an action/event has been executed? Hence, the importance of notifications.
Overtime, I have always used either react-toast or react-hook-toast to handle notifications. However, out of a budding curiosity, i chose to create my own custom Notification component from scratch using react createContext hook.
Initially, i tried creating this as a custom hook. However, the challenge was managing and keeping the state consistent. Hence, I chose to use react createContext hook.
The benefit of react createContext hook is that it helps you to pass props to only components that need it. Thereby, helping you manage the state of your react application, and avoid prop drilling.
Enough yapping, below is my solution.
step 1
import React, { createContext, useEffect, useState } from "react";
type NotificationContextType = {
notification: boolean;
setNotification: (value: boolean) => void;
};
export const NotificationContext = createContext<
NotificationContextType | undefined
>(undefined);
export const NotificationProvider = ({
children,
}: {
children: React.ReactNode;
}) => {
const [notification, setNotification] = useState<boolean>(false);
useEffect(() => {
const interval = setTimeout(() => setNotification(false), 3000);
return () => clearTimeout(interval);
}, [notification]);
return (
<NotificationContext.Provider value={{ notification, setNotification }}>
{children}
</NotificationContext.Provider>
);
};
In the code above, I defined the type for my context NotificationContextType, then I created a NotificationContext constant. Afterwards, I created the NotificationProvider.
step 2
import { useContext } from "react";
import { NotificationContext } from "@/context/NotificationContext";
export const useNotification = () => {
const context = useContext(NotificationContext);
if (!context) {
throw new Error(
"useNotification must be used within a NotificationProvider"
);
}
return context;
};
I created a useNotification Hook.
Finally, below is the component where it is being used.
type NotificationProps = {
message: string;
};
const Notification = ({ message }: NotificationProps) => {
const { notification } = useNotification();
if (!notification) return null;
return (
<div className="fixed bottom-[5rem] flex justify-center w-full">
<div
className={`
bg-[#333333] rounded-md p-4 text-white m-auto flex gap-2 w-[22rem]`}
>
<img src='image.png' alt="link-copied-icon" />
<p>{message}</p>
</div>
</div>
);
};
export default Notification;
import { useNotification } from "@/hooks/useNotification";
const PreviewHeader = () => {
const { setNotification } = useNotification();
return (
<header className=" h-[4.875rem] container">
<nav className="bg-[#ffffff] w-full flex h-full rounded-md items-center justify-between pl-6 pr-4">
<NavLink
to="/profile"
className="text-[#633cff] border border-[#633CFF] px-4 py-2 text-sm rounded-md font-medium"
>
Back to Editor
</NavLink>
<Button
variant={"saveButton"}
className="bg-[#633cff]"
onClick={() => setNotification(true)}
>
Share Link
</Button>
</nav>
</header>
);
};
export default PreviewHeader;
That's it.
Please feel free to share your thoughts. Thanks
Top comments (0)