Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it safe to use ReactDOM.createPortal() with document.body?

I understand that it's probably a bad idea to ReactDOM.render() into document.body. But are there any issues with using ReactDOM.createPortal() with document.body?

Tried looking for examples of React going bonkers when you render into body so I could test it out with createPortal but I wasn't able to find any.

To put things into context, here's a sample usage I'm speaking about:

import React from 'react';
import ReactDOM from 'react-dom';

export default class Modal extends React.Component {
    render() {
        return ReactDOM.createPortal(
            <div className='modalContainer'>
                <div className='modalBox'>
                    {this.props.children}
                </div>
            </div>,
            document.body
        );
    }
}

Haven't run into any issues with this pattern but I'd like to know if there are consequences as I start adding more libraries.

like image 501
Daniel Avatar asked Mar 27 '18 04:03

Daniel


People also ask

What is ReactDOM createPortal?

Portals provide a first-class way to render children into a DOM node that exists outside the DOM hierarchy of the parent component. ReactDOM. createPortal(child, container) The first argument ( child ) is any renderable React child, such as an element, string, or fragment.

Is ReactDOM render necessary?

Because you won't be able to render an app to DOM without it. Your app probably has reactdom. render() in it and you don't realize it. Those are probably standalone examples—you need it once for every app.

Why we are using ReactDOM?

ReactDOM is a package that provides DOM specific methods that can be used at the top level of a web app to enable an efficient way of managing DOM elements of the web page. ReactDOM provides the developers with an API containing the following methods and a few more.

Which method is part of ReactDOM?

ReactDOM provides the developers with an API containing the methods such as render(), findDOMNode(), unmountComponentAtNode(), hydrate(), and createPortal().

When does reactdom createportal respond to user input?

When a ReactDOM.createPortal is used in conjunction with a container in another window, the components do not respond to user input until after setState or forceUpdate are called on the parent component of the portal.

What is the use case for a portal in reactdom?

It renders the children into `domNode`. // `domNode` is any valid DOM node, regardless of its location in the DOM. return ReactDOM.createPortal( this.props.children, domNode ); } A typical use case for portals is when a parent component has an overflow: hidden or z-index style, but you need the child to visually “break out” of its container.

Is react portal a new concept?

Portal is not new concept in the react community. Many libraries are available that supports this kind of functionality. e.g react-portal and react-gateway. What happens when rendering any react app? Generally, when rendering any React application, a single DOM element is used to render the whole React tree.

Does context event bubbling work with react portal?

Features like context work exactly the same regardless of whether the child is a portal, as the portal still exists in the React tree regardless of position in the DOM tree. This includes event bubbling.


2 Answers

I am pretty sure that the same rules apply to portals as to usage of ReactDOM.render. According to the portals documentation you provided, it is true that the portal is from the React's point of view a child of the React application (consider eg. the direction of the synthetic DOM event propagation), but physically the portal lives in separate context where React still needs to keep track of state changes and be in sync with the DOM.

If the parent of such context is the body element, then the same amount of unwanted surprises is in stake like elements being inserted to it via 3rd party tools as stated in Dan Abramov's article. Simply put: As those DOM mutations from 3rd parties happen outside of React's control BUT modify the part of DOM that IS under React's control, it can lead to conflicts and inconsistencies.

Another point @RIYAJ KHAN has risen in his comment is what happens if suddenly the portal becomes parent of the application, especially if React sees them the other way around? The least I can think of are inconsistencies between native and synthetic DOM event propagation, where those two would propagate events in opposite directions between app and portal containers, which can get mind boggling if you often use both types of event handling (eg. synthetic in React component's event handlers and the native ones in RxJS operators).

Last but not least, what if you have more such portals which should be on the top DOM level, are you going to reuse the body for all of them? That together with the 2 points above would create a turmoil.

The safest way is to create dedicated divs under the body just for the portals, this way they stay clean and free of unwanted magic.

like image 199
Skocdopole Avatar answered Oct 14 '22 05:10

Skocdopole


Our experience so far on Material-UI has been that it's safe: https://github.com/mui-org/material-ui/issues/21626. We haven't seen any limitations reported by one of the 1m+ developers using the library yet.

like image 39
Olivier Tassinari Avatar answered Oct 14 '22 05:10

Olivier Tassinari