DEV Community

Cover image for React: Using portals to make a modal popup

React: Using portals to make a modal popup

Andrew Bone on August 07, 2020

This week we'll be making a modal popup, we'll be making it using portals and inert. Both of which are very cool in their own right. I'll be making...
Collapse
 
nickytonline profile image
Nick Taylor

Nice! We use portals on DEV as well. For the moment, just in the moderation center though.

github.com/forem/forem/blob/master...

Looking forward to your next post Andrew!

Collapse
 
link2twenty profile image
Andrew Bone • Edited

The DEV codebase looks so different to when I used to know it 😅

I've been looking at crayons a little today, some really nice stuff in there 😁

Collapse
 
nickytonline profile image
Nick Taylor • Edited

Crayons is the code name for our design system. You can see our work in progress Storybook at storybook.dev.to. I thought storybook.forem.com was working, but looks like some DNS stuff needs to be sorted in Netlify.

We also have a bunch of Tailwind inspired utility classes. However, they are not surfaced in documentation at the moment. This PR fixes that.

You can see the utility class docs in the Storybook for the PR.

Collapse
 
xodeeq profile image
Babatunde Adenowo

I'm implementing this using typescript and the latest nextjs 13. Two things:

  1. I think this is a perfect idea (using react portals), as my main layout.tsx is a server component and putting a dynamic client-rendered portal directly in it may result in component poisoning somehow (maybe not, but I'm being cautious).
  2. I'm struggling with finding the right typescript types for a lot of the properties, primarily, the props to the Portal wrapper component. I'll be glad if anyone could help me out with the right types. Currently, I have { children: React.ReactNode, parent: React.ReactNode, className: string} but I see that the parent type is still wrong as React.ReactNode doesn't have the appendChild property or method.

Great piece @link2twenty, Thank you.

Collapse
 
rain84 profile image
rain84

@link2twenty , thank you for interesting article

I have a question.
Why you are using

[27].indexOf(e.which)
Enter fullscreen mode Exit fullscreen mode

instead of

e.which === 27
Enter fullscreen mode Exit fullscreen mode

?

Collapse
 
link2twenty profile image
Andrew Bone

It's for future proofing, whenever I want a specific key I do it that way so I can add extra keys to the array down the line.

For instance if I wanted to add the enter key I would do this.

[27, 13].indexOf(e.which)

Collapse
 
n1rjal profile image
Nirjal Paudel

That is a really nice blog. I actually wanted to learn on making a popup form on react portal popup. How can we do that ? Do you hav any idea

Collapse
 
link2twenty profile image
Andrew Bone

You can use this code and pass in a form as the child.

Collapse
 
n1rjal profile image
Nirjal Paudel

The method is techically correct but not "REACT esk". If I would use, say email and password field, in the form and make it a controlled component by putting value and setValue. Each time the state changes due to onChange, the code freezes for split second and UX will be poor

Thread Thread
 
link2twenty profile image
Andrew Bone

That's React's official documentation. A redraw, due to state change, should not cause anything to freeze.

Thread Thread
 
link2twenty profile image
Andrew Bone

Here's an example

Collapse
 
arqex profile image
Javier Marquez

Very nice the idea of wrapping the createPortal call in a component to allow the animation! I'll definitely use it.

Collapse
 
link2twenty profile image
Andrew Bone

In this code it needs to be an HTMLElement, I would generally use ref.