Portal
Declarative component for using React portals.
Basic usage
By default all Portal's children will be rendered into a new div in the end of the document.body.
New div will be created when Portal is mounted and removed from DOM when Portal will unmounted.
import { useState } from 'react';
import { Portal } from '@krutoo/utils/react';
function App() {
const [modalOpen, setModalOpen] = useState(false);
return (
<>
<button onClick={() => setModalOpen(true)}>Show modal</button>
{/* By default portal will render content to new div in end of body */}
{open && (
<Portal>
<div className='my-modal'>Hello, from modal!</div>
</Portal>
)}
</>
);
}
Target container
You can specify element to render into by defining container prop, it may be element or function.
import { useState } from 'react';
import { Portal } from '@krutoo/utils/react';
function App() {
const [modalOpen, setModalOpen] = useState(false);
return (
<>
<button onClick={() => setModalOpen(true)}>Show modal</button>
{open && (
<Portal container={document.querySelector('#portal')}>
<div className='my-modal'>Hello, from modal!</div>
</Portal>
)}
</>
);
}
Connect
By default if container is not connected to the document yet - document.body.appendChild(container) will be called.
You can disable it behavior by setting connect={false}.
You can also can specify custom connect implementation as function that receives container.
import { useState } from 'react';
import { Portal } from '@krutoo/utils/react';
function App() {
const [modalOpen, setModalOpen] = useState(false);
return (
<>
<button onClick={() => setModalOpen(true)}>Show modal</button>
{open && (
<Portal container={document.querySelector('#root')} connect={false}>
<div className='my-modal'>Hello, from modal!</div>
</Portal>
)}
</>
);
}
Cleanup
By default when Portal component unmounts, it removes created container element from document.
If custom container was specified - nothing will be done.
If you want to clean up custom container, just pass true to cleanup prop.
import { useState } from 'react';
import { Portal } from '@krutoo/utils/react';
function App() {
const [modalOpen, setModalOpen] = useState(false);
return (
<>
<button onClick={() => setModalOpen(true)}>Show modal</button>
{open && (
<Portal container={document.querySelector('#root')} cleanup={false}>
<div className='my-modal'>Hello, from modal!</div>
</Portal>
)}
</>
);
}