Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

you have multiple copies of React loaded #2818

Closed
iceafish opened this issue Jan 7, 2016 · 62 comments
Closed

you have multiple copies of React loaded #2818

iceafish opened this issue Jan 7, 2016 · 62 comments
Labels
core Infrastructure work going on behind the scenes

Comments

@iceafish
Copy link

iceafish commented Jan 7, 2016

version 0.14.1 produces this error:
Uncaught Error: Invariant Violation: 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).

If remove node_modules/material-ui/node_modules/react,the error isn't present.

@neenaoffline
Copy link

Happens while using DropDownMenus too. Removing node_modules_material-ui/node_modules/react helps avoid the error as well.

@newoga
Copy link
Contributor

newoga commented Jan 8, 2016

@iceafish @neenaoffline Are you having this issue only on 0.14.1 and not 0.14.0? Can you show me which code is causing the error or what component it is complaining about?

This might be related to #2802.

If one of are able to try what's in master, that would be helpful too.

@mlarcher
Copy link

mlarcher commented Jan 9, 2016

I am facing the same error message in 0.14.2 with the Datepicker component (in node 4.2.3/npm 2.14.7).
I am using ES6 imports syntax, and I believe #2802 could be the root cause of the issue, but installing babel-plugin-add-module-exports and pluging it to my browserify bundle task didn't seem to help.
I have built was is currently on material-ui's master branch and got the same issue.
Please let me know if I can provide more info to help investigate.

@newoga
Copy link
Contributor

newoga commented Jan 9, 2016

@mlarcher I tried writing a test DatePicker on 0.14.2 and it looks like its working on my side. Are you getting an error on import? Or on render? Could you show me your import statement?

Also you shouldn't need babel-plugin-add-module-exports in your project (or more specifically you shouldn't need it for material-ui components). We already include it as part of the material-ui build in 0.14.2.

Maybe try deleting your node_modules and reinstalling too.

@mlarcher
Copy link

mlarcher commented Jan 9, 2016

I already tried deleting node_modules and reinstalling, with no luck.
Here is the complete error output:

Uncaught Invariant Violation: 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).

invariant @ invariant.js:39
ReactOwner.addComponentAsRefTo  @ ReactOwner.js:67
attachRef @ ReactRef.js:23
ReactRef.attachRefs @ ReactRef.js:42
attachRefs  @ ReactReconciler.js:21
assign.notifyAll  @ CallbackQueue.js:65
ON_DOM_READY_QUEUEING.close @ ReactReconcileTransaction.js:81
Mixin.closeAll  @ Transaction.js:202
Mixin.perform @ Transaction.js:149
Mixin.perform @ Transaction.js:136
assign.perform  @ ReactUpdates.js:86
flushBatchedUpdates @ ReactUpdates.js:147
wrapper @ ReactPerf.js:66
NESTED_UPDATES.close  @ ReactUpdates.js:45
Mixin.closeAll  @ Transaction.js:202
Mixin.perform @ Transaction.js:149
assign.perform  @ ReactUpdates.js:86
flushBatchedUpdates @ ReactUpdates.js:147
wrapper @ ReactPerf.js:66
Mixin.closeAll  @ Transaction.js:202
Mixin.perform @ Transaction.js:149
ReactDefaultBatchingStrategy.batchedUpdates @ ReactDefaultBatchingStrategy.js:62
enqueueUpdate @ ReactUpdates.js:176
enqueueUpdate @ ReactUpdateQueue.js:24
ReactUpdateQueue.enqueueCallback  @ ReactUpdateQueue.js:108
ReactComponent.setState @ ReactComponent.js:67
openDialog  @ date-picker.js:244
(anonymous function)  @ date-picker.js:273
setTimeout (async)    
_handleInputTouchTap  @ date-picker.js:272
ReactErrorUtils.invokeGuardedCallback @ ReactErrorUtils.js:71
executeDispatch @ EventPluginUtils.js:79
executeDispatchesInOrder  @ EventPluginUtils.js:102
executeDispatchesAndRelease @ EventPluginHub.js:43
executeDispatchesAndReleaseTopLevel @ EventPluginHub.js:54
forEachAccumulated  @ forEachAccumulated.js:23
EventPluginHub.processEventQueue  @ EventPluginHub.js:259
runEventQueueInBatch  @ ReactEventEmitterMixin.js:18
ReactEventEmitterMixin.handleTopLevel @ ReactEventEmitterMixin.js:34
handleTopLevelWithoutPath @ ReactEventListener.js:93
handleTopLevelImpl  @ ReactEventListener.js:73
Mixin.perform @ Transaction.js:136
ReactDefaultBatchingStrategy.batchedUpdates @ ReactDefaultBatchingStrategy.js:62
batchedUpdates  @ ReactUpdates.js:94
ReactEventListener.dispatchEvent  @ ReactEventListener.js:204

Error seems to be on render (but I'm not utterly sure about that).
Here is what the usage looks like:

import React, { Component, PropTypes } from 'react';
import { FormattedMessage } from 'react-intl';
import DatePicker from 'material-ui/lib/date-picker/date-picker';
// injectTapEventPlugin needs to be called for datepicker to work!
import injectTapEventPlugin from 'react-tap-event-plugin';

injectTapEventPlugin();

class BoxedInput extends Component {

  constructor() {
    super();
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick(e) {
    e.preventDefault();
    this.props.onAction();
  }

  render() {
    var actionButton = !this.props.onAction ? null : (
      <button
        type="button"
        className="boxedInput_button"
        onClick={this.handleClick}
      >
        <FormattedMessage id={this.props.actionText || 'boxedInput_defaultActionMsg'}/>
      </button>
    );

    var boxedInputLabel = !this.props.label ? '' : (
      <span className="boxedInput_labelText">
        <FormattedMessage id={this.props.label}/>
      </span>
    );

    const input = this.props.type !== 'date' ? (
      <input
        type={this.props.showPassword ? 'text' : this.props.type}
        placeholder={this.props.placeholder}
        className={`boxedInput ${!this.props.type ? '' : `boxedInput--${this.props.type}`}`}
        {...this.props.field}
      />
    ) : (
      <DatePicker
        hintText={this.props.placeholder}
      />
    )

    return (
      <div
        className={`boxedInputWrapper ${!this.props.type ? '' : `boxedInputWrapper--${this.props.type}`} ${this.props.customClass || ''} `}
      >
        <label className="boxedInput_label">
          {boxedInputLabel}
          {input}
          {actionButton}
        </label>
      </div>
    );
  }
}

BoxedInput.displayName = 'BoxedInput';


BoxedInput.propTypes = {
  onAction: PropTypes.func,
  actionText: PropTypes.string,
  customClass: PropTypes.string,
  placeholder: PropTypes.string,
  type: PropTypes.string,
  label: PropTypes.string,
};

export default BoxedInput;

@newoga
Copy link
Contributor

newoga commented Jan 9, 2016

@mlarcher Thanks for copying the code. Could you try this as your import instead?

import {DatePicker} from 'material-ui/lib/date-picker';

The DatePicker component isn't currently default exported, not sure when that was changed...

Edit: Actually, your code should work. Let me look into this some more.

@newoga
Copy link
Contributor

newoga commented Jan 9, 2016

@mlarcher I can't reproduce this. I'm not having a problem importing date-picker in my projects in 0.14.2 with your same import statement. The docs are importing the date-picker the same way too.

The biggest difference is I (or the docs) don't use browserify. Would you be able to put a sample reproducible example on github somewhere that I can clone and try?

@mlarcher
Copy link

mlarcher commented Jan 9, 2016

@newoga: here is a stripped down version that shows the bug :
test.zip

@newoga
Copy link
Contributor

newoga commented Jan 9, 2016

@mlarcher I'd recommend creating a project where your app.jsx is simply something like this:

import React from 'react';
import ReactDOM from 'react-dom';
import DatePicker from 'material-ui/lib/date-picker/date-picker';
import injectTapEventPlugin from 'react-tap-event-plugin';
injectTapEventPlugin();

ReactDOM.render(
  <DatePicker />,
  document.getElementById('mainContainer')
);

I did that in your project an am still having your problem. More specifically, the component renders, and this error logs to console when you click the component and the dialog appears:

Uncaught Error: Invariant Violation: 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

I didn't identify the root cause, but I'm not able to reproduce this in my webpack based projects. I'm also not able to reproduce this in this project's browserify example. I'd probably look very closely at your build process to make sure that your not doing anything that could accidentally be bundling React multiple times. You may be able to find some help of StackOverflow with browserify as I'm not too familiar with it.

Note: if you're going by the example, I just created #2857 so make sure to include those before running it.

@crantila
Copy link

Hi everyone. I was having this problem with my own project, but I solved it.

The problem is that "material-ui" 0.14.2 wants React "^0.14.6" but my project was using React 0.14.3, so npm installed an extra copy of React, just for material-ui.

When I upgraded my project to React 0.14.6, then reinstalled material-ui, npm used the top-level React as a "peerDependency." Now React is only loading once—problem solved!

@alitaheri
Copy link
Member

@crantila That's really weird. Why did npm install a copy for material-ui? React is a peer dependency for material-ui. npm doesn't automatically install peer dependencies. what version of npm are you using?

@mlarcher
Copy link

@newoga There is indeed a problem with the way I generate the libs.js bundle. It may be due to the fact that the files in bundle.js are listed from the dependencies of my package.json, and even though 'material-ui' is an explicit dependency, 'material-ui/lib/date-picker/date-picker' isn't. Or maybe it is an issue with having react required by ES6 imports in my code and require() calls in meterial-ui. Anyhow, I'll have to find a better way to handle this kind of scenarios.

Still, when I stop excluding libs from the bundling task and load all js from the same bundle, I don't have the invariant error anymore, but now the calendar opens but doesn't have any content :

I guess it is another issue, though, so I'll check if it is already referenced and open a new ticket if it isn't.

Edit: Actually, this problem is just due to the way the datepicker resizes when chrome dev tools is opened. No biggies, even though it could be improved. Problem is fixed for me, thanks for your help @newoga

@crantila
Copy link

@alitaheri I'm using npm 2.14.12, which ships with the "stable" Node release. There's a warning about how peer dependencies won't be installed automatically, but it does still install them.


It seems like there are several different ways to cause multiple React versions to load, and they all result in material-ui not working. Would it be possible for material-ui to detect when this is happening, and to print a message in the console that contains a link to a (wiki?) page with more information about what might be causing the problem?

@MayasHaddad
Copy link

Please, React should be removed from the dependencies of the lib.

Check this excellent example of react-router

React is used as a devDependency instead.

Cheers for the good job you guys are doing!

@MayasHaddad
Copy link

P.S.
If you want to avoid dependency issues related to the react version used by material-ui, then use "peerDependencies" property as such

@oliviertassinari
Copy link
Member

React should be removed from the dependencies of the lib.

What do you mean?

@MayasHaddad
Copy link

@oliviertassinari I had to remove react from within material-ui to get rid of "... or you have multiple copies of React loaded"

@MayasHaddad
Copy link

*in my local dep tree

@alitaheri
Copy link
Member

With npm v3+ I never experienced this issue. Could you update your npm and try again?

@neenaoffline
Copy link

React is only a devDependency in material-ui as well, but that causes the
conflict if you're using an older version of npm because it would install
two copies anyway without attempting to avoid duplication. I believe this
changed in npm 3.

https://github.com/npm/npm/blob/master/CHANGELOG.md
http://blog.npmjs.org/post/91303926460/npm-cli-roadmap-a-periodic-update

On Tue, Jan 12, 2016 at 11:23 AM, Ali Taheri Moghaddar <
notifications@github.com> wrote:

With npm v3+ I never experienced this issue. Could you update your npm and
try again?


Reply to this email directly or view it on GitHub
#2818 (comment)
.

neena

@oliviertassinari
Copy link
Member

I was using npm 2 until recently and I had no issue. We declare react as a "dependency" at two places in our package.json.
Once as a peerDependency. This makes npm 2 installing react at the root node_modules, so that shouldn't be an issue.
We also declare it as a devDependency, that is just ignored during a npm install from your project directory.
How can we reproduce this issue?

@MayasHaddad
Copy link

I removed node_modules and reinstalled, everything is ok now.
I'll consider upgrading to npm3 though.

@ahmadferdous
Copy link

@oliviertassinari
I started my project with relay-starter-kit. At that time it used react and react-dom exact version 0.14.3. When I added module material-ui to my project, React Dev Tools (chrome extension) complained about multiple react versions being loaded. This is what I found when I checked:

$ npm list react
├─┬ material-ui@0.14.2
│ └── react@0.14.6 
└── react@0.14.3 

$ node -v
v4.2.4
$ npm -v
2.14.12

When I upgraded to npm v3, the issue was tackled by npm itself by keeping a single version of react. However, as far as I know, relay is currently bound to npm v2. So a solution in material-ui with npm v2 would have been nice!

@dagatsoin
Copy link

I am facing a similar problem with Meteor 1.3.beta4 and npm 2.14.14.

I also tried with NPM3 but when I launch the app the console tells me that 'react' can't be found even if it is included with meteor add react

@djalmajr
Copy link

I have a project called ui that uses material-ui as base, then I import the ui to another project. The error happens to me when I import certains components to my ui project:

captura1

captura2

captura3

captura4

When the size of the bundle increases like that, this error occurs.

The same to this components: ListItem, MenuItem, IconButton...

@apires
Copy link

apires commented Apr 4, 2016

The issue for us is that we had shrinkwrapped 0.14.7 and material-ui 0.15-alpha-2 isn't shrinkwrapped so it pulled react 0.14.8.

Would be nice if the deps were shrinkwrapped or more specific about versions.

@haradakunihiko
Copy link

@mlarcher @ahmadferdous
maybe this will help.
npm/npm#12290

@mlarcher
Copy link

@haradakunihiko: this issue is related to npm-shrinkwrap, which is not involved on the problematic scenario, so I wonder if it could work in our case. I should give it a try, but for now we moved to npm3 to avoid the issue.

Just to make it clear, our situation is the following:
We have a 0.14 version of React in our package.json and npm@2 installs a newer version of the same minor within node_modules/material-ui instead of aknowledging a peer dependency satifying material-ui's requirements is already present.

@haradakunihiko
Copy link

@mlarcher Actually, I'm definitely in the same situation, but with react-bootstrap. React-bootstrap has peer dependencies for react and it installs newer version of react inside react-bootstrap module.
And it is very likely because of shrink-wrap (npm/npm#5135 (comment)). This could happen also with material-ui.
I think this kind of issue is not caused by a single problem, but shrink-wrap with npm@2 would be one of the causes.
Anyway, updating npm to ver.3 would be the best solution (and sadly, I can not update for some reason...).

@cody-lettau
Copy link

We were seeing these same issues while developing a common react components library that utilized Material UI. After trying many of the different solutions that were suggested, the following worked for us:

Adding below to our webpack config:

resolve: {
    alias: {
      react: path.resolve('./node_modules/react'),
    }
}

Thanks to @mdarif for the tip!

@agriboz
Copy link

agriboz commented Jun 23, 2016

Making a alias solves my problem @cody-lettau @mdarif thanks anyways

@arzavj
Copy link

arzavj commented Jul 14, 2016

@felipethome I'm having the same problem, specifying react as an external resource to browserify did not fix the import of ./React. How did you get around it? FYI I'm using grunt and browserify.

@felipethome
Copy link
Contributor

@arzavj I don't use grunt, but give a look at the gulpfile.js of this seed. Maybe it helps you.

@arzavj
Copy link

arzavj commented Jul 16, 2016

Got it! Thanks!

@sunny-g
Copy link

sunny-g commented Aug 26, 2016

@cody-lettau did you add that to the webpack config for the library, or for the project that uses that library?

@cody-lettau
Copy link

@sunny-g It was added to the library we were building. This library utilized material-ui.

@sunny-g
Copy link

sunny-g commented Aug 26, 2016

Thank you for the prompt response! I ended up using externals in the library's webpack.config.js and that fixed the error.

@jarecsni
Copy link

jarecsni commented Nov 7, 2016

felipethome commented on 23 Feb
Thanks @felipethome for your comment and the github example, you solved my issue! It was the 'react-addons-transition-group' not being listed in the external dependencies (next to React, etc) for browserify. It's a bit scary that something can go this horribly wrong without clear indication of what the issue is. Thanks again!

Grace951 added a commit to Grace951/react-image-carousel that referenced this issue Dec 26, 2016
Grace951 added a commit to Grace951/react-image-carousel that referenced this issue Dec 26, 2016
Grace951 added a commit to Grace951/react-image-carousel that referenced this issue Dec 26, 2016
Grace951 added a commit to Grace951/react-image-carousel that referenced this issue Dec 26, 2016
Grace951 added a commit to Grace951/react-image-carousel that referenced this issue Dec 26, 2016
Grace951 added a commit to Grace951/react-image-carousel that referenced this issue Dec 26, 2016
Grace951 added a commit to Grace951/react-image-carousel that referenced this issue Dec 26, 2016
@BBlackwo
Copy link

My issue was a bit different. I had 2 different Webpack bundles and both were pulling in React. One of my NPM modules in the 2nd bundle did a require('react') and require('react-dom').

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',
}

@liquidslr
Copy link

I had the same issue and i solved it by removing all the node modules and using yarn to install all the dependencies again.

@zannager zannager added the core Infrastructure work going on behind the scenes label Dec 21, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
core Infrastructure work going on behind the scenes
Projects
None yet
Development

No branches or pull requests