Skip to content

Instantly share code, notes, and snippets.

@viclafouch
Created December 18, 2020 10:53
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 viclafouch/1ec9d1956903a6d0e8be00484fc9320b to your computer and use it in GitHub Desktop.
Save viclafouch/1ec9d1956903a6d0e8be00484fc9320b to your computer and use it in GitHub Desktop.
A custom React Hook to create a Portal.
import { useState, useRef, useEffect, useCallback } from 'react'
import { createPortal } from 'react-dom'
export default function usePortal() {
const [isOpen, setIsOpen] = useState(false)
const portal = useRef(null)
const openPortal = useCallback((callback) => {
if (!portal.current) {
portal.current = document.createElement('div')
document.body.appendChild(portal.current)
if (typeof callback === 'function') {
callback(portal)
}
setIsOpen(true)
}
}, [])
const closePortal = useCallback(() => {
if (portal.current) {
setIsOpen(false)
document.body.removeChild(portal.current)
portal.current = null
}
}, [])
useEffect(() => () => {
if (portal.current) {
document.body.removeChild(portal.current)
}
}, [])
const Portal = useCallback((children) => {
if (portal.current !== null) return createPortal(children, portal.current)
return null
}, [])
return {
isOpen,
openPortal,
closePortal,
Portal,
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment