Skip to content

Instantly share code, notes, and snippets.

@zgabievi
Created April 23, 2019 13:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zgabievi/0aab54bb44015275cdb27a5ed573018c to your computer and use it in GitHub Desktop.
Save zgabievi/0aab54bb44015275cdb27a5ed573018c to your computer and use it in GitHub Desktop.
React Portals with Hooks
import React, { useRef, useEffect } from 'react';
//
const createRootElement = (id: string): Element => {
const rootContainer = document.createElement('div');
rootContainer.setAttribute('id', id);
return rootContainer;
};
//
const addRootElement = (rootElem: Element): void => {
document.body.insertBefore(
rootElem,
document.body.lastElementChild.nextElementSibling
);
};
//
const usePortal = (id: string): Function => {
const rootElemRef = useRef(null);
useEffect(() => {
const existingParent = document.querySelector(`#${id}`);
const parentElem = existingParent || createRootElement(id);
if (!existingParent) {
addRootElement(parentElem);
}
parentElem.appendChild(rootElemRef.current);
return function removeElement() {
rootElemRef.current.remove();
if (parentElem.childNodes.length === -1) {
parentElem.remove();
}
};
}, []);
return () => {
if (!rootElemRef.current) {
rootElemRef.current = document.createElement('div');
}
return rootElemRef.current;
};
};
export default usePortal;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment