ReactJS - PopUp组件错误:目标容器不是DOM元素

时间:2015-06-22 13:34:23

标签: javascript jquery popup reactjs react-jsx

我正在尝试在ReactJS中创建组件来创建PopUps但是我在react-with-addons.js中遇到了这个错误:

  

错误:不变违规:_registerComponent(...):目标容器不是DOM元素。

这是我的代码:

HTML:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8"> 
    <script type="text/javascript" src="react-0.13.3/build/react-with-addons.js"></script>
    <script type="text/javascript" src="react-0.13.3/build/JSXTransformer.js"></script>
    <script type="text/javascript" src="react-router/lib/umd/ReactRouter.js"></script>
    <link rel="stylesheet" href="bootstrap/css/bootstrap.min.css"/>
    <link rel="stylesheet" href="bootstrap/css/bootstrap-theme.min.css"/>

    <script type="text/javascript" src="jquery/jquery-1.11.1.min.js"></script>
    <script type="text/javascript" src="bootstrap/js/bootstrap.min.js"></script>

    <title>WS-JAVA-REST</title>

    <style>
        .row { padding-top: 10px; }
    </style>
  </head>
  <body>
    <!-- contenu -->
    <div id="content">
        <script type="text/jsx" src="test.js"></script>
    </div>
  </body>
</html>

的Javascript

/** @jsx React.DOM */

var clicked = function(){
  mountedPopup.setState({visible: true, pretendStateChanged: Date.now() });
  mountedComponent.setState({pretendStateChanged: Date.now() }) ;
}

var popupClicked = function(){
  mountedPopup.setState({visible: false, pretendStateChanged: Date.now() });
  mountedComponent.setState({pretendStateChanged: Date.now() }) ;
};

var Component = React.createClass({
  getInitialState: function() {
    return {pretendStateChanged: Date.now() };
  },
  render: function(){
    return React.DOM.div(null,
      React.DOM.a({onClick: clicked, href: "javascript:void(0);"}, "Show popup"),
      React.DOM.br(null),
      React.DOM.span(null, "State: " + this.state.pretendStateChanged)
    );
  }
});

var Popup = React.createClass({
  getInitialState: function() {
    return {visible: false, pretendStateChanged: Date.now()};
  },
  componentWillUpdate: function(nextProps, nextState){
    if (!this.state.visible && nextState.visible) {
      this.popUp();
    }

    /* closed by application */
    if (this.state.visible && !nextState.visible) {
      this.closePopUp();
    }
  },
  popUp: function(){
    var self  = this;
    var parent = this.getDOMNode().parentNode;
    $.magnificPopup.open({
      items: {
        src: parent,
        type: 'inline'
      },
      removalDelay: 30,
      callbacks: {
        afterClose: function() {
          if (self.state.visible){
            /* closed by user pressing ESC */
            self.setState({visible: false});
          }
        }
      }
    });
  },
  closePopUp: function(){
    $.magnificPopup.close();
  },
  render: function(){
    return React.DOM.div(null,
      React.DOM.a({
        onClick: this.props.onClickHandler,
        href: "javascript:void(0);"
      }, "Button inside popup"),
      React.DOM.br(null),
      React.DOM.span(null, "State: " + this.state.pretendStateChanged)
    );
  }
});

var mountedComponent = React.render(
  <Component/>,
  document.body.childNodes[1]
);

var mountedPopup = React.render(
  <Popup onClickHandler={this.popupClicked} />,
  document.body.childNodes[3]
);

所以我完全错过了什么?为什么我收到此错误?有人可以帮帮我吗?

1 个答案:

答案 0 :(得分:3)

您的问题的简短回答是原始组件尚未加载,因此没有目标DOM节点来加载Popup组件。 React.render有一个可选的第三个参数,用于在渲染完成时触发的回调。因此,以下内容适用于您的情况:

var mountedPopup;
var mountedComponent = React.render(
  <Component/>,
  document.body.childNodes[1],
  function() {
     mountedPopup = React.render(
        <Popup onClickHandler={this.popupClicked} />,
        document.body.childNodes[3]
     );
  }
);

然而,正如其他人所提到的,这段代码也有一些重要的建议:

  1. 绝对不要使用document.body.childNodes [N]作为语法
  2. 你可能应该避免在可能的情况下使用弹出窗口库... jQuery和React并不总能很好地协同工作
  3. 您将此结构化为两个单独的组件,并使用全局变量和函数将它们绑定在一起。弹出组件作为另一个组件的子组件可能会更好地构建。通过这种方式,您将能够使用父组件来管理状态,弹出窗口可以只响应这些更改。它还允许您将大量代码封装在父组件中。如果这样做,您将不需要通过变量名来引用这些组件,甚至不需要为它们分配变量。这是一种反模式,应该避免使用。
  4. “this.popupClicked”可能无法按预期工作。由于它是一个全局函数,您可以将其称为“popupClicked”。更好的是,您最终应该将其作为父容器中的方法(见上文)