The usePortal
hook provides a way to create a portal in React, allowing you to render children into a DOM node that exists outside the hierarchy of the parent component. This is useful for modals, tooltips, and other UI elements that need to break out of their parent container.
Add the utility
npx @ivnatsr/ezreact add use-portal
import { createPortal } from ' react-dom '
import { useState, useLayoutEffect } from ' react '
const isServer = typeof window === ' undefined '
export function usePortal () {
const [ wrapperElement ] = useState ( () => {
if ( isServer ) return null
return document . createElement ( ' div ' )
if ( wrapperElement === null ) return
document . body . appendChild ( wrapperElement )
document . body . removeChild ( wrapperElement )
renderPortal : ( children ) => {
return wrapperElement === null ? null : createPortal ( children , wrapperElement )
import { createPortal } from ' react-dom '
import { useState, useLayoutEffect, type ReactPortal, type ReactNode } from ' react '
const isServer = typeof window === ' undefined '
export function usePortal () {
const [ wrapperElement ] = useState < HTMLDivElement | null > ( () => {
if (isServer) return null
return document . createElement ( ' div ' )
if (wrapperElement === null ) return
document . body . appendChild (wrapperElement)
document . body . removeChild (wrapperElement)
renderPortal : ( children : ReactNode ) : ReactPortal | null => {
return wrapperElement === null ? null : createPortal (children , wrapperElement)
Return
This hook returns an object containing the following method:
renderPortal
: A function that takes children
as an argument and returns a React portal. If the wrapperElement
is null
, it returns null
.
Example
import { usePortal } from ' ./path/to/use-portal '
const PortalExample = () => {
const { renderPortal } = usePortal ()
< div style = { { background: ' lightblue ' , padding: ' 20px ' } } >
export default PortalExample