DEV Community

Cover image for 【React.js】Making a Simple Toast Message Component with useContext and React Portal -part1-
Kota Ito
Kota Ito

Posted on • Updated on

【React.js】Making a Simple Toast Message Component with useContext and React Portal -part1-

I have been a good friend with React-Toastify for a long time.
So whenever I need a toast mesage in my app I just go fot it.

But this time I made it from scratch using useContext and React portal so that the toast message fits in my app design concept.

First of all, I defined a React Portal component.

Why using React Portal

Why do we need to make a portal to implement a toast message to begin with?

Reason being that you can render the message component separate from the rest of the code in your app.
This allow you to avoid z-index and styling issues. Also, you can insert the message component at the root level of your app so it doesn't affect other content.

Define a React Portal

import React from 'react';
import ReactDom from 'react-dom';

type Props = {
  children: React.ReactNode;
  selector: string; //a CSS selector to select the target DOM element
};

const ClientPortal = ({ children, selector }: Props): React.ReactPortal | null => {
  const ref = React.useRef<Element>();
  const [mounted, setMounted] = React.useState(false);
// track whether the portal has been mounted

  React.useEffect(() => {
    const elm = document.querySelector(selector);
    if (elm) {
      ref.current = elm;
      setMounted(true);
    }
  }, [selector]);

  return mounted && ref.current ? ReactDom.createPortal(children, ref.current) : null;
};

export default ClientPortal;
Enter fullscreen mode Exit fullscreen mode

In ClientPortal component, you have useEffect, which first searches for the DOM element specified by the selector, and if found, sets ref.current to the found element.
Also it sets mounted state to true, indicating the target for portal is ready.

This component utilizes ReactDOM.createPortal to render its children into a DOM element referred to by ref.current, effectively creating a portal that allows the children to be mounted onto a different part of the DOM tree than their parent component.

At the end, there is code that exports the component as the default export, so it can be imported and used in other files.

continue to part2

in part 2, I'm going to show how I, personally, made a Toast Messsage popper component.

from Unsplash
taken by maxim bober

Top comments (0)