ReactJS-弹出窗口组件错误:目标容器不是DOM元素

ReactJS - PopUp Component Error: Target container is not a DOM element

本文关键字:DOM 元素 目标 窗口组件 错误 ReactJS-      更新时间:2023-09-26

我试图在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]
);

那么我是不是完全错过了什么?为什么我会出现此错误?有人能帮我吗?

问题的简短答案是,原始组件尚未加载,因此没有目标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"。更好的是,您最终应该将其作为一个方法合并到父容器中(见上文)