loading...
Cover image for React Portals in 3 Minutes

React Portals in 3 Minutes

jh3y profile image Jhey Tompkins ・3 min read

Grasp this awesome API for escaping DOM restraints whilst creating Portals πŸ•ΉπŸ˜Ž

What is it?

An API for rendering components outside of your app’s DOM hierarchy.

ReactDOM.createPortal(<Component/>, DOMElement)
Intuitive API πŸ‘

For those in camp TL;DR scroll down for a demo!

Why?

Perfect for scenarios where CSS styles are restraining your elements. For example, stacking(z-index) and overflow issues. You could even render things in a new window! 😎

Link to HackerNoon Article

How?

Instead of returning an element in a component’s render method, return a portal.

const Outsider = () => ReactDom.createPortal(<div>I am outside</div>, document.body)

const App = () => <Outsider/>

Outsider renders as a direct descendant of document.body πŸ‘

When to use?

  • Modals
  • Tooltips
  • Floating menus
  • Widgets

Scope + Bubbling

A brilliant thing about portals is that a component rendered in a portal acts as if it is still in the React tree. It behaves like a normal React child. Pass it props, it will react to updates, etc.

Events fired in a portal will also bubble up through the React tree! Check out the example in the React docs.

Link to React Docs

Basic example (Modal)

Let’s start with a common use case β€” the Modal. Modals are a great example of where we may need to render a component outside of the current DOM structure.

Our Modal will render based on a state value in the app.

const Modal = ({ children, onClose, open }) =>
  open
    ? ReactDOM.createPortal(
      <div className='modal'>
        <button className='modal__close' onClick={onClose}>&times;</button>
        { children }
      </div>,
      document.body
    )
  : null

For our example, we will render the Modal on document.body. Our Modal is a functional component that accepts children, onClose and open as props.

Here it is in action!

A silly example

Remember the video game "Portal"?

Link to Portal Video Game Wikipedia Article

Let’s create a scene πŸ˜…

Let’s start with a Man πŸƒ. We are going to use Greensock's Draggable to create a draggable Man.

Link to GreenSock documentation for Draggable

Now let’s create a scene with a "Portal". Our man will be bound by the app container.

const App = () => (
  <Fragment>
    <Man bounds={rootNode} />
    <div className="portal portal--in"/>
  </Fragment>
)

That gives us

Draggable Man concept where the Man Component is bound to a container

Now let’s get ReactDOM.createPortal involved πŸ˜ƒ

We add an element into the DOM outside of our app (#outside). We also create state for tracking whether our Man is in or out of the app container.

We then use createPortal to render a Portal in #outside. And if outside is true we will use createPortal to render our Man in that outer element πŸ‘

<Man
  bounds={outside ? outsideElement : rootNode}
  onRelease={onRelease}
  outside={outside}
/>
<div className="portal portal--in" ref={innerPortalRef} />
{createPortal(
  <div ref={outerPortalRef} className="portal portal--out" />,
  outsideElement
)}
const ManRender = () => (
  <div className="man" ref={manRef} role="img">
    πŸƒ
  </div>
);

return outside ? createPortal(<ManRender />, bounds) : <ManRender />;

Our Man now invokes an onRelease function too. This checks our cursor position against our portal bounds on release. If we release over a portal, we toggle the state value. All the code is in the demo, there's not much to it πŸ‘

Clip of the working portal. Man component can be dragged in and out of the app container via the fictional portal

If you use your dev tools to inspect the DOM, you’ll see the render happening outside #app πŸ‘

Notes

That’s it!

A 3-minute intro to portals in React!

Link to React Docs on Portals

As always, any questions or suggestions, please feel free to leave a response or tweet me 🐦! I'd love it if you connected with me on the socials 😎

Posted on by:

jh3y profile

Jhey Tompkins

@jh3y

I make awesome things for awesome people!

Discussion

pic
Editor guide
 

I am so glad you used an example from the portal game here. Perfect.

 

I felt obliged πŸ˜…I'm glad it's appreciated!

 

I read articles about using react portals, but never really felt the need to use it itself.... until now. Modals appear to be the perfect use-case, I've been giving far too high zIndexs to my modals :)

Thank you immensely for the post Jhey. It has truly widened my perspective on coding with React.

 

Hey joon πŸ‘‹
No problem! I'm glad I could help 😊We can do some pretty cool things with Portals 😎

 

Really awesome introduction to Portals, I feel the need to try it.

 

Thanks Ronald! 😊I appreciate that. Try it out, it's quite cool what opportunities it provides.