Search code examples
reactjsamd

Global React does not play nice with AMD React


I'm getting weird weird behaviour when rendering a component using an AMD-loaded React, when a global React already exists on the page. Click events on components are getting fired when they should not be.

A look at the DOM implies that this stems from multiple React instances (one global, one AMD in my case) not being aware of each other, but this poses a problem when loading an AMD module at runtime that depends on React, into a page that also includes React.

How can I resolve this clash?

Reproduction

I can make a component like this:

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

But as soon as I add another component using another instance of React then click the first button, then it calls the click event on the second loaded button:

// .... 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

If I use the existing, global version of React in this call (rather than ReactFromAmd, then it works as expected. jsbin


Solution

  • This has been fixed in version 0.14.2: http://jsbin.com/tesodoxape/1/edit?html,js,output