Material-ui: Uncaught Error: addComponentAsRefTo(...): Only a ReactOwner can have refs. You might be adding a ref to a component that was not created inside a component's `render` method, or you have multiple copies of React loaded (details:

Created on 15 Mar 2017  路  4Comments  路  Source: mui-org/material-ui

Hi. I have seen this issue opened and closed quite a few times but none seem related to what I am doing.

I have 2 repos:

  • One components repo, a set of curated components based on material-ui

    • contains material-ui, react, and react-dom as a devDependancy

  • One core repo, the core application that consumes the components using imports.

    • basically a create-react-app with material-ui added along with the components repo above.

Everything seems to work fine until I include an element that is clickable. As soon as I click on a component (like <AppBar /> the console is filled with errors:

Uncaught Error: addComponentAsRefTo(...): Only a ReactOwner can have refs. You might be adding a ref to a component that was not created inside a component's `render` method, or you have multiple copies of React loaded (details: https://fb.me/react-refs-must-have-owner).
    at invariant (invariant.js:44)
    at Object.addComponentAsRefTo (ReactOwner.js:68)
    at attachRef (ReactRef.js:23)
    at Object.ReactRef.attachRefs (ReactRef.js:42)
    at ReactCompositeComponentWrapper.attachRefs (ReactReconciler.js:23)
    at CallbackQueue.notifyAll (CallbackQueue.js:76)
    at ReactReconcileTransaction.close (ReactReconcileTransaction.js:80)
    at ReactReconcileTransaction.closeAll (Transaction.js:206)
    at ReactReconcileTransaction.perform (Transaction.js:153)
    at ReactUpdatesFlushTransaction.perform (Transaction.js:140)

The button also turns black:

image

In my components repo I have ensured that react and material-ui are listed as devDependencies. I have also tried adding and removing them from peerDependencies. I have externalized them both with webpack from the coponents repo:

  externals: {
    'react': 'react',
    'material-ui': 'material-ui',
    'react-dom': 'react-dom',
    }

I have tried adding react as an alias in webpack and I have also tried adding many different node modules to the externals key without any success. These work fine if they are part of the core app, but not when consumed from the components repo from another application. Any help is greatly appreciated. A colleague and I have roughly 10 hours into troubleshooting this one issue. This seems to affect every clickable element.

We would really love to build custom components based on material-ui (think a full fledged Sidenav based on material-ui components) however this is the one thing keeping us back.

And yes, I have tried removing node_modules and reinstalling them with yarn/npm 馃槃

This might be as simple as just giving some guidance on how to include material-ui in a standalone repo that others can use. Thank again.

Versions

  • Material-UI: 0.17.1
  • React: 15.4.2
  • Webpack: 2.2.1
  • npm: 3.10.10
  • node: 6.10.0
question

Most helpful comment

Hi. I just wanted to circle back in case anyone else needs to refer to this. This ended up being a combination of a few things:

  • don't use NPM link or a symbolic link to link your node module to your "core" repo. This caused webpack (at least v2) to include a second copy of react when serving the code.
  • make sure your excludes are correct. The magic combination that worked for us is:
externals: [
    "react-addons-create-fragment",
    "react-addons-transition-group",
    "react-event-listener",
    'material-ui',
    {
      "react-router-dom": {
        root: 'react-router-dom',
        commonjs2: 'react-router-dom',
        commonjs: ['react-router-dom'],
        amd: 'react-router-dom',
      },
      react: {
        root: 'React',
        commonjs2: 'react',
        commonjs: ['react'],
        amd: 'react',
      },
      'react-dom': {
        root: 'ReactDOM',
        commonjs2: 'react-dom',
        commonjs: ['react-dom'],
        amd: 'react-dom',
      },
    }
  ],
  • use bundle analyzer to make sure that 2 copies aren't getting pulled in. Even if bundle analyzer says there aren't 2 copies, be sure you aren't using npm link or sym link to link your node modules (see the first point)

Thanks again for the examples and pointing us in the right direction.

All 4 comments

Perhaps take a look at other projects that are doing this: http://www.material-ui.com/#/discover-more/related-projects. I'm afraid we don't have the bandwidth to troubleshoot implementation issues, sorry.

Closing as a Question.

Understood. Thanks for the links!

Hi. I just wanted to circle back in case anyone else needs to refer to this. This ended up being a combination of a few things:

  • don't use NPM link or a symbolic link to link your node module to your "core" repo. This caused webpack (at least v2) to include a second copy of react when serving the code.
  • make sure your excludes are correct. The magic combination that worked for us is:
externals: [
    "react-addons-create-fragment",
    "react-addons-transition-group",
    "react-event-listener",
    'material-ui',
    {
      "react-router-dom": {
        root: 'react-router-dom',
        commonjs2: 'react-router-dom',
        commonjs: ['react-router-dom'],
        amd: 'react-router-dom',
      },
      react: {
        root: 'React',
        commonjs2: 'react',
        commonjs: ['react'],
        amd: 'react',
      },
      'react-dom': {
        root: 'ReactDOM',
        commonjs2: 'react-dom',
        commonjs: ['react-dom'],
        amd: 'react-dom',
      },
    }
  ],
  • use bundle analyzer to make sure that 2 copies aren't getting pulled in. Even if bundle analyzer says there aren't 2 copies, be sure you aren't using npm link or sym link to link your node modules (see the first point)

Thanks again for the examples and pointing us in the right direction.

Thanks @timothystewart6!

Using webpack-bundle-analyzer helped me track down the issue that my 2 different Webpack bundles were both pulling in React and ReactDOM.

I fixed it by adding the following to my 2nd bundle's Webpack config

externals: {
  // Don't bundle react or react-dom
  'react': 'React',
  'react-dom': 'ReactDOM',
}
Was this page helpful?
0 / 5 - 0 ratings

Related issues

iamzhouyi picture iamzhouyi  路  3Comments

finaiized picture finaiized  路  3Comments

ghost picture ghost  路  3Comments

rbozan picture rbozan  路  3Comments

ghost picture ghost  路  3Comments