UNPKG

@mui/material

Version:

Material UI is an open-source React component library that implements Google's Material Design. It's comprehensive and can be used in production out of the box.

121 lines (87 loc) • 3.82 kB
--- productId: material-ui title: React Portal component components: Portal githubLabel: 'scope: portal' --- # Portal The Portal component lets you render its children into a DOM node that exists outside of the Portal's own DOM hierarchy. {{"component": "@mui/internal-core-docs/ComponentLinkHeader", "design": false}} ## Introduction Portal is a utility component built around [React's `createPortal()` API](https://react.dev/reference/react-dom/createPortal). It gives you the functionality of `createPortal()` in a convenient component form. It's used internally by the [Modal](/material-ui/react-modal/) and [Popper](/material-ui/react-popper/) components. :::info According to [the React docs](https://react.dev/reference/react-dom/createPortal), portals are useful when "you need the child element to visually 'break out' of its container"—for instance, modals and tooltips, which need to exist outside of the normal flow of the document. ::: Normally, children of a component are rendered within that component's DOM tree. But sometimes it's necessary to mount a child at a different location in the DOM. The Portal component accepts a `container` prop that passes a `ref` to the DOM node where its children will be mounted. The following demo shows how a `<span>` nested within a Portal can be appended to a node outside of the Portal's DOM hierarchy—click **Mount children** to see how it behaves: ```tsx import * as React from 'react'; import Portal from '@mui/material/Portal'; import { Box } from '@mui/system'; export default function SimplePortal() { const [show, setShow] = React.useState(false); const container = React.useRef(null); const handleClick = () => { setShow(!show); }; return ( <div> <button type="button" onClick={handleClick}> {show ? 'Unmount children' : 'Mount children'} </button> <Box sx={{ p: 1, my: 1, border: '1px solid' }}> It looks like I will render here. {show ? ( <Portal container={() => container.current!}> <span>But I actually render here!</span> </Portal> ) : null} </Box> <Box sx={{ p: 1, my: 1, border: '1px solid' }} ref={container} /> </div> ); } ``` ## Basics ### Import ```jsx import Portal from '@mui/material/Portal'; ``` ## Customization ### Server-side Portals The DOM API isn't available on the server, so you need to use the `container` prop callback. This callback is called during a React layout effect: ```jsx <Portal container={() => document.getElementById('filter-panel')!}> <Child /> </Portal> ``` :::error The Portal component cannot be used to render child elements on the server—client-side hydration is necessary. This is because React doesn't support the [`createPortal()` API](https://react.dev/reference/react-dom/createPortal) on the server. See [this GitHub issue](https://github.com/react/react/issues/13097) for details. ::: # Portal API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Portal](https://mui.com/material-ui/react-portal/) ## Import ```jsx import Portal from '@mui/material/Portal'; // or import { Portal } from '@mui/material'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | children | `node` | - | No | | | container | `HTML element \| func` | - | No | | | disablePortal | `bool` | `false` | No | | > **Note**: The `ref` is forwarded to the root element. ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/mui-material/src/Portal/Portal.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/mui-material/src/Portal/Portal.tsx)