Global React 不能很好地与 AMD React 配合使用

Global React does not play nice with AMD React

当页面上已经存在全局 React 时,使用 AMD 加载的 React 渲染组件时,我会出现奇怪的行为。组件上的点击事件在不应触发的情况下被触发。

看一下 DOM 暗示这源于多个 React 实例(一个全局的,一个 AMD 在我的例子中)没有意识到彼此,但这在加载 AMD 模块时会造成问题依赖于 React 的运行时,进入还包含 React 的页面。

我该如何解决这个冲突?

复制

我可以制作这样的组件:

var ButtonComponent = React.createClass({
  onButtonClick: function(){
    alert(this.props.data + ' click event fired');
  },
  render: function() {
    return React.DOM.button({onClick: this.onButtonClick}, this.props.data);
  }
});

(function(){ // create vanilla

  var ButtonList = React.createClass({
    render: function() {
      return React.DOM.div({}, React.createElement(ButtonComponent, {data: this.props.data}));
    }
  });

  React.render(React.createElement(ButtonList, {data: 'button that was loaded by the page'}), document.getElementById('page-load-target'));

})();

jsbin

但是一旦我使用另一个 React 实例添加另一个组件然后单击第一个按钮,它就会在第二个加载的按钮上调用单击事件:

// .... as above ....

(function(){ // create using amd

  require.config({
    paths: {
      'react': '//fb.me/react-with-addons-0.12.2.min'
    }
  });

  window.setTimeout(function(){ 
    require(['react'], function(ReactFromAmd){ 
      ReactFromAmd.render(ReactFromAmd.createElement(ButtonComponent, {data: 'button that was loaded by AMD'}), document.getElementById('amd-load-target'));
    });
  }, 1000)

})();

jsbin

如果我在此调用中使用现有的全球版本的 React(而不是 ReactFromAmd,那么它会按预期工作。jsbin

ButtonComponent的祖先s(React实例)和ReactFromAmd.createElement创建的组件不同,但它们在同一个虚拟DOM -- 这是不允许的。

如果你不介意用 browserify 替换 AMD,我只是想出了一个方法让 isolated/remotely-loaded React 组件很好地共存。

(如有需要,待续)

这已在 0.14.2 版中修复:http://jsbin.com/tesodoxape/1/edit?html,js,output