Search code examples
reactjsbootstrap-4react-bootstrap4-modal

React Bootstrap4 modal placement


I've got a component that opens a bootstrap modal (using react-bootstrap4-modal)

It opens and closes using this

{this.state.inEditMode ? <MemberModal /> : null}

However, because the component is already nested somewhere in the DOM, it's not a valid placement for bootstrap modal markup. It leaves a nasty white bar at the bottom, which I confirmed does not happen if it's located within the outermost <App/> div tag.

Is there a simple way to fix this? Or will it require me putting all of my modal components within <App/> and changing the state of <App/> from within nested children?


Solution

  • This is a z-index stacking issue and was a common problem until React introduced portals. Dan Abrimov from the FB team put together a code pen with an example that can be found here.

    Portals provide a first-class way to render children into a DOM node that exists outside the DOM hierarchy of the parent component.

    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. For example, dialogs, hovercards, and tooltips.

    Normally, when you return an element from a component’s render method, it’s mounted into the DOM as a child of the nearest parent node:

    render() {
      // React mounts a new div and renders the children into it
      return (
        <div>
          {this.props.children}
        </div>
      );
    }
    

    However, sometimes it’s useful to insert a child into a different location in the DOM:

    render() {
      // React does *not* create a new div. 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
      );
    }