antew
antew

Reputation: 7478

React-Bootstrap Popover on non-react element - wrong position and invariant error

This JSFiddle illustrates the problem.

I'm trying to use the react-bootstrap library to show a Popover on an existing page built without React. The fiddle has an example of a vanilla Bootstrap popover and one created with react-bootstrap.

There are three errors:

I'm sure I'm doing something incorrectly, I just don't know what it is.

var Portal = ReactBootstrap.Portal;
var Popover = ReactBootstrap.Popover;

// Create the popup dynamically and show it with bootstrap
var $username = $('#username');
var showBootstrapPopover = function() {
    $username.popover({            
        placement: 'top',
        title: 'Vanilla Bootstrap Popover',
        content: 'I am a vanilla Bootstrap Popover'
    }).popover('show');
}

var MyPopover = React.createClass({
  render: function() {
    return (
      <Portal container={document.body} 
              placement="bottom" 
              target={() => document.querySelector(this.props.target)} 
              show={true}>
        <Popover title="React Popover">
          <div>I should be on the bottom of the textarea</div>
        </Popover>
      </Portal>
    );
  }
});

var reactUsername = React.render(<MyPopover target="#username" show={true} />, document.querySelector('#username'));

showBootstrapPopover();
reactUsername.setState({ show: true });
<div>
  <textarea id="username" rows="1" cols="60" type="text" class="form-control" placeholder="Username"></textarea>
</div>

Upvotes: 1

Views: 1371

Answers (1)

okm
okm

Reputation: 23871

The error occurs during picking DOM Node of children of <MyPopover />, because in the line

var reactUsername = React.render(<MyPopover .../>, 
                                 document.querySelector('#username'));

the <MyPopover /> is mounted into <textarea#username>, which is incorrect as it actually sets the render() result of <MyPopover /> as the text of the textarea node...After that React can not find the expected DOM node, <noscript></noscript> here, and have to complain that the DOM was unexpectedly mutated. You could mount to another mountable DOM Node to get rid of this error.

Furthermore, <Portal> only put your <Popover> into document.body, to position the <Popover> right below the textarea, try <Position> or <Overlay>. See JSFiddle

Upvotes: 3

Related Questions