外部脚本在页面更改react-router之后不会加载

时间:2016-11-03 21:08:08

标签: reactjs react-router

我正在使用react-router。我在两个反应组件中嵌入了相同的外部小部件。小部件第一次加载或者刷新页面时加载正常。问题是当我更改页面时,小部件不再加载。请看我的代码:

var { Router, Route, IndexRoute, Link, browserHistory } = ReactRouter

var MainLayout = React.createClass({
  render: function() {
    return (
      <div className="app">
        <header className="primary-header"></header>
        <aside className="primary-aside">
          <ul>
            <li><Link to="/">Home</Link></li>
            <li><Link to="/page1">Page1</Link></li>
            <li><Link to="/page2">Page2</Link></li>
          </ul>
        </aside>
        <main>
          {this.props.children}
        </main>
      </div>
      )
  }
})

var Home = React.createClass({
  render: function() {
    return (<h1>Home Page</h1>)
  }
})

var SearchLayout = React.createClass({
  render: function() {
    return (
      <div className="search">
        <header className="search-header"></header>
        <div className="results">
          {this.props.children}
        </div>
        <div className="search-footer pagination"></div>
      </div>
      )
  }
})

var PageOne = React.createClass({
  componentDidMount: function() {
    const plumxScript = document.createElement("script");
    plumxScript.src = "//d39af2mgp1pqhg.cloudfront.net/widget-popup.js";
    plumxScript.async = true;
    document.body.appendChild(plumxScript);
 },

  render: function() {
    return (
        <div
            href="https://plu.mx/plum/a/?doi=10.1371/journal.pone.0056506"
            className="plumx-plum-print-popup"
            data-hide-when-empty="true"
            data-popup="left"
            data-size="medium"
            target="_blank">
        </div>
      )
  }
})

var PageTwo = React.createClass({
  componentDidMount: function() {
    const plumxScript = document.createElement("script");
    plumxScript.src = "//d39af2mgp1pqhg.cloudfront.net/widget-popup.js";
    plumxScript.async = true;
    document.body.appendChild(plumxScript);
  },

  render: function() {
    return (
        <div
            href="https://plu.mx/plum/a/?doi=10.1371/journal.pone.0056506"
            className="plumx-plum-print-popup"
            data-hide-when-empty="true"
            data-popup="left"
            data-size="medium"
            target="_blank">
        </div>
      )
  }
})

ReactDOM.render((
  <Router>
    <Route path="/" component={MainLayout}>
      <IndexRoute component={Home} />
      <Route component={SearchLayout}>
        <Route path="page1" component={PageOne} />
        <Route path="page2" component={PageTwo} />
      </Route> 
    </Route>
  </Router>
), document.getElementById('root'))

单击Page1并加载小部件,单击Page2,理论上小部件应该重新加载,但它没有。如果我再次点击第1页,则小部件无法加载。

此处的完整代码:https://codepen.io/vh_ruelas/pen/MbgdOm

1 个答案:

答案 0 :(得分:0)

问题似乎与您正在加载的脚本有关,而不是与路由器反应。显然,当你多次加载时,它并没有像预期的那样工作,这看起来并不像一个干净的解决方案。

如果您只加载一次脚本,那么您将面临一个问题,即稍后呈现的占位符节点无法自动转换,因为脚本只在加载时初始化它们({{ 3}})。幸运的是,该脚本添加了一个(显然未记录的)函数,您可以调用它来解决此问题:window.__plumX.widgets.popup.wireUp()

但是脚本与React结合的另一个问题是:它严重修改了React渲染的DOM,导致了各种各样的问题。有很多相关信息,例如source。除了在React中重新实现小部件之外,最好的方法似乎是让React呈现容器<div>,然后手动插入小部件节点。

这是一个解决这两个问题的课程,似乎按照你想要的方式工作:

var PlumXPopup = React.createClass({
  componentDidMount() {
    this.appendNode();
    this.appendScript();
  },

  appendNode: function() {
    const plumxNode = document.createElement("div");
    plumxNode.className = "plumx-plum-print-popup";
    plumxNode.setAttribute('href', 'https://plu.mx/plum/a/?doi=10.1371/journal.pone.0056506');
    plumxNode.setAttribute('data-hide-when-empty', 'true');
    plumxNode.setAttribute('data-popup', 'left');
    plumxNode.setAttribute('data-size', 'medium');
    plumxNode.setAttribute('target', '_blank');
    this.divNode.appendChild(plumxNode);
  },

  appendScript: function() {
    if (document.getElementById('plumx-script')) {
      if (window.__plumX) {
        window.__plumX.widgets.popup.wireUp();
      }
      return;
    }
    const plumxScript = document.createElement("script");
    plumxScript.id = 'plumx-script';
    plumxScript.src = "//d39af2mgp1pqhg.cloudfront.net/widget-popup.js";
    plumxScript.async = true;
    document.body.appendChild(plumxScript);
  },

  render: function() {
    var _this = this;
    return <div ref={function(ref) { _this.divNode = ref }} />
  }
});

您可以在PageOne和PageTwo中使用它而不是占位符<div>,并且还可以删除在那里加载的脚本。您可能还想添加在创建占位符节点时使用的道具。