React usePortal hook
Creates a portal, allowing rendering of children outside the parent component.
- Use the
useState()
hook to create a state variable that holds therender()
andremove()
functions for the portal. - Use
ReactDOM.createPortal()
andReactDOM.unmountComponentAtNode()
to create a portal and a function to remove it. Use theuseCallback()
hook to wrap and memoize these functions ascreatePortal()
. - Use the
useEffect()
hook to callcreatePortal()
and update the state variable any timeel
's value changes. - Finally, return the
render()
function of the state variable.
const usePortal = el => { const [portal, setPortal] = React.useState({ render: () => null, remove: () => null, }); const createPortal = React.useCallback(el => { const Portal = ({ children }) => ReactDOM.createPortal(children, el); const remove = () => ReactDOM.unmountComponentAtNode(el); return { render: Portal, remove }; }, []); React.useEffect(() => { if (el) portal.remove(); const newPortal = createPortal(el); setPortal(newPortal); return () => newPortal.remove(el); }, [el]); return portal.render; }; const App = () => { const Portal = usePortal(document.querySelector('title')); return ( <p> Hello world! <Portal>Portalized Title</Portal> </p> ); }; ReactDOM.createRoot(document.getElementById('root')).render( <App /> );