meteor / react-packages

Meteor packages for a great React developer experience
http://guide.meteor.com/react.html
Other
573 stars 158 forks source link

Multiple Reacts and "Only a ReactOwner can have refs" error #168

Closed SachaG closed 8 years ago

SachaG commented 8 years ago

I'm running into the following error with my package:

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

It seems it's because the full React code is being included in my package code, which means I end up with two copies of React loaded in memory.

According to this similar issue, it might have something to do with using Browserify inside my package?

stubailo commented 8 years ago

I wonder if this has something to do with peer dependencies - I have only tested this approach with packages that depend on React directly.

So the way the Browserify transform is supposed to work is by replacing require('react') with Package['react-runtime'].React.require('react'), which prevents Browserify from following the dependency and actually bundling React. Do you have an example app or something so that I can look at the built output?

SachaG commented 8 years ago

This will reproduce the bug: https://github.com/SachaG/react-bug-repro

It won't trigger the error but if you inspect the utilities:meteor-griddle code it contains React.

SachaG commented 8 years ago

Oh actually I'm not sure… It does seem like it contains Underscore for some reason? I'm wondering if maybe the original Griddle package is to blame for some of this.

SachaG commented 8 years ago

Maybe a better way to reproduce the bug is to run the actual app on the react branch: https://github.com/DiscoverMeteor/BookApp/tree/react (private repo but I've given you access)

ryanlanciaux commented 8 years ago

One of the Griddle authors here.. We are using underscore in this version (I wish we initially set it up to allow the user to choose underscore / lodash). In 1.0, it doesn't require either but pulls in just a couple of specific modules from lodash.

Please let me know if there's anything we're doing that's causing trouble for you and we'll see if we can get it resolved in the Griddle project. :+1: I'm not super familiar with the Meteor side of things but our goal is that it should work in anything really.

ryanlanciaux commented 8 years ago

Additionally, is this using griddle from npm or from the full build?

stubailo commented 8 years ago

This is from NPM, and it's reasonably likely the problem is on our end. I'll check it out soon!

dagatsoin commented 8 years ago

Hi. I ran to this error after npm install material-ui in meteor 1.3.beta4 It seems that material ui imports reacts as well. Do you know how can I prrvent material ui to load react twice?

tmeasday commented 8 years ago

@stubailo I had a look at this and I'm pretty sure it's just something in cosmos:browserify / externalify rather than anything to do with peer dependencies.

I made a test app: https://github.com/tmeasday/test-griddle

If you run it and look at the compiled source for the griddle package, you'll see lines like

var React = require('react'); 

This should however have been transformed by externalify to this mess:

var React = (typeof window !== "undefined" ? window['Package']['react-runtime']['React']['require'] : typeof global !== "undefined" ? global['Package']['react-runtime']['React']['require'] : null)("react");

I have no idea why it is not happening. The package seems to be configured identically to other packages I've written that similarly depend on and require('react').

PS it's suspicious also that there's no .browserify.js.cached or .browserify.js.map file being created. I'm not sure if that's relevant but it's different to what I see in other packages.

tmeasday commented 8 years ago

If I get a chance I'll poke further but I have to run now.

oskareke commented 8 years ago

@SachaG Did you happen to find a solution for this issue?

SachaG commented 8 years ago

The general solution I found was to not use Npm.depends in your package, and generally try to stick to importing packages via npm install whenever you can (i.e. no Npm.depends, no meteorhacks:npm, etc.).

stubailo commented 8 years ago

Yes, in Meteor 1.3 the solution is to use NPM install. If you use NPM 3 you're basically guaranteed to have exactly one version of React in your app.

tmeasday commented 8 years ago

Closing this