Create React Portals Typed Safe

enetojara

Ernesto Jara Olveda

Posted on March 14, 2022

Create React Portals Typed Safe

today I will show you how to create a react portals with typescript the Propper way.

import ReactDOM from "react-dom";
import * as React from "react";

const defaultProps = {
  tag: "section",
  create:false,
  className: "",
};

type Props = React.HTMLAttributes<HTMLElement> & typeof defaultProps &{
  /**
   * the html tag you would like to use as wrapper.
   * 
   * @default "section"
   */
    tag: keyof JSX.IntrinsicElements;
    id: string;
    /**
     * if true a new node/htmlTag will be created, else the html tag already exists.
     * @default false.
     */
    create: boolean;
}

const Portal: React.FC<Props> = props => {
  const { tag, create, id, className, children, ...rest } = props;
    const el = create ? document.createElement(tag) : document.getElementById(id);

    const wrapper = React.useRef<HTMLElement>(el);


        React.useEffect(() => {
        const current = wrapper.current as HTMLElement;
        if (!current) return;

            current.setAttribute("id", id);
            current.setAttribute("class", className);

            type K =  keyof typeof rest;

            Object.keys(rest).forEach(key => {
              const val = rest[key as K] as K
                current.setAttribute(key, val);
            });

            document.body.appendChild(current);


        return () => {
            if (create) {
                document.body.removeChild(current);
            }
        };
    }, [wrapper,id, create, className, rest]);

      if (!wrapper.current) {
        return <>{null}</>;
    }

    return ReactDOM.createPortal(children, wrapper.current);
};

export default Portal;
Enter fullscreen mode Exit fullscreen mode
💖 💪 🙅 🚩
enetojara
Ernesto Jara Olveda

Posted on March 14, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

Create React Portals Typed Safe
react Create React Portals Typed Safe

March 14, 2022