Using a React 16 Portal to do something cool

David Gilbertson
Nov 7, 2017 · 3 min read

React 16 is here, and one of the more interesting additions is ‘Portals’.

Portals let you render a bit of React-controlled DOM outside of the parent component. The React docs explain it nicely, using the example of a modal. It works well for tooltips, too (here’s one I made earlier).

But none of that is very interesting. Let’s do something weird…

Since all a portal does is take an element and append it to some other element, you aren’t limited to sticking it elsewhere in the current document. You can append it to the body in a different document, perhaps a document in an entirely different window.

Below I have a base page (on ze left) that has a counter and a crimson button, and a window (on the right) that’s part of the same React app, and also a forest (in the background).

The fact that the window on the right is the same React app is what you’re supposed to be excited about.

Image for post
Image for post
You can to take my word for it that the numbers go up in unison, or click

Everything you see in the picture above (except the trees) is in the one component below.

You’ve worked out by now that <MyWindowPortal> is a little bit special, and anything inside it is going to get rendered in a different window.

You are correct, and I am proud of you. Specifically, <MyWindowPortal> does two things:

  1. Opens a new browser window when it mounts
  2. Creates a ‘portal’ and appends props.children to the body of the new window

Isn’t that the coolest thing?

I’m so excited I have to go for a walk.

I saw a duck!

Below is the body of the component from above. The part that’s new in React 16 is ReactDOM.createPortal on line 11 — that’s where the magic happens.

I apologise for putting the lifecycle methods in a weird order

Does that make sense? The component doesn’t return something, it does something elsewhere.

Maybe another way to think about it is this: normally, a parent component says to a child component: “hey, render some DOM, then append the results to me”, and the child component does what it’s told. But in this case, the obstreperous child says “No! I’m gonna render stuff in a different window and write a blog post about it!”

Now, I know what you’re thinking.

You’re thirsty and you’re wondering if you should have some water. Yes, go have a drink.

The other thing you’re probably thinking is: what good is it being able to inject some DOM into a blank window if it’s unstyled? Maybe if it’s Craigslist or Wikipedia no one will notice, but your site is beautiful, you can’t have your little chat window pop out thing being all times-new-romany.

Well, good news, everybody!

Image for post
Image for post

At first I hoped there would be an easy way to copy the styles into the new window. Then I remembered that my life is little more than a series of meaningless tasks to fill the minutes and hours, their only purpose to keep me distracted from the deep, howling emptiness inside.

So writing the function myself was fun!

Here it is:

All this styleSheet business is not stuff that I actually know about, so I look forward to being told the smart way to do this in the comments.

Now I can copy the styles across just after opening the new window, like so:

Here it all is in a codepen:

I don’t think it will work from within the Medium app on iOS/Android, so hit the codepen icon in the top right to open it in a browser.

I think this is the end of the blog post.

Bye, everybody!

HackerNoon.com

#BlackLivesMatter

Sign up for Get Better Tech Emails via HackerNoon.com

By HackerNoon.com

how hackers start their afternoons. the real shit is on hackernoon.com. Take a look.

By signing up, you will create a Medium account if you don’t already have one. Review our Privacy Policy for more information about our privacy practices.

Check your inbox
Medium sent you an email at to complete your subscription.

David Gilbertson

Written by

I like web stuff.

HackerNoon.com

Elijah McClain, George Floyd, Eric Garner, Breonna Taylor, Ahmaud Arbery, Michael Brown, Oscar Grant, Atatiana Jefferson, Tamir Rice, Bettie Jones, Botham Jean

David Gilbertson

Written by

I like web stuff.

HackerNoon.com

Elijah McClain, George Floyd, Eric Garner, Breonna Taylor, Ahmaud Arbery, Michael Brown, Oscar Grant, Atatiana Jefferson, Tamir Rice, Bettie Jones, Botham Jean

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store