On usePortal
A React Hook to make using Portals easier.
Here's a gist showing a usePortal
hook to make using React Portals easier.
import {
createPortal as createReactPortal,
unmountComponentAtNode,
} from "react-dom";
import { useState, useCallback, useEffect } from "react";
export let usePortal = (el: Element = document.body) => {
let [portal, setPortal] = useState<{
render: Function;
remove: Function;
}>({
render: () => null,
remove: () => null,
});
const createPortal = useCallback((el) => {
let Portal = ({ children }: { children: Element }) =>
createReactPortal(children, el);
let remove = () => unmountComponentAtNode(el);
return { render: Portal, remove };
}, []);
useEffect(() => {
if (el) unmountComponentAtNode(el);
let newPortal = createPortal(el);
setPortal(createPortal(el));
return () => {
newPortal.remove();
};
}, [el, createPortal]);
return portal.render;
};
Example
import { usePortal } from "somewhere";
let Foo = () => {
let Portal = usePortal(/* maybe a document.querySelector call */);
return <Portal>{/* something */}</Portal>;
};