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

null owner in addComponentAsRefTo hard to fix #5631

Closed
joIivier opened this issue Dec 9, 2015 · 9 comments
Closed

null owner in addComponentAsRefTo hard to fix #5631

joIivier opened this issue Dec 9, 2015 · 9 comments

Comments

@joIivier
Copy link

joIivier commented Dec 9, 2015

I am migrating my UI from react-1.13.3 to 1.14.3 and encountered the following error messages when loading my page:

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

I tried to fix it but I still have it with the following simple component:

const Test = React.createClass({

  handleClick() {
    console.log(this.refs.test.value);
  },
  render() {
    return <div><input ref="test" onClick={this.handleClick}/></div>;
  }
});

export default {
  render(targetId) {
    return ReactDOM.render(<Test hint="root"/>, document.getElementById(targetId));
  }
};

So clearly my ref is set in the render method in this code that fails.

I investigated about the possibility of having twice React loaded and npm ls|grep react@ has only one line. I am not sure this proves anything since we have a complex build that generates our code (and probably the issue is somewhere in our build), but I ensured React code is only once in our output script, I also put a breakpoint in ReactCurrentOwner line 20 and was hit only once. I don't know if this is sufficient but for me we load React only once, so I went deeper.

When debugging I see that in the call to addComponentAsRefTo: function (component, ref, owner), owner is null. I then put breakpoints when ReactCurrentOwner.current is set to a non null value (ReactCompositeComponent lines 146 and 605, ReactMultiChild line 196 and 211). When I start my application, the breakpoint in ReactCompositeComponent:146 is hit twice (and at this time, this._currentElement.props is {hint:'root} but each time it is reset to null on line 150. The call to addComponentAsRefTo is done outside these two windows where the owner is not null.

What can I do to investigate more?

@hmeerlo
Copy link

hmeerlo commented Dec 28, 2015

I have exactly the same problem and can not get my head around it. The weird thing is that it seems to be related with the build setup. It works fine in my development setup but it fails with the above problems when built on Jenkins and running in a Docker container.

@gaearon
Copy link
Collaborator

gaearon commented Dec 28, 2015

Typically this means you have two Reacts bundled on the page: #2402

Try checking whether you're having node_modules/react with 0.14 and some other package depending on React dragging its own outdated version as a dependency?

This situation will be better if you ask the maintainer of that package to specify React as a peerDependency instead. Then you can switch to npm@3.x which doesn't install peer dependencies automatically. This way you can't get the duplicates.

I also wrote about this problem here.

@hmeerlo
Copy link

hmeerlo commented Dec 28, 2015

thanx @gaearon for your seemingly endless patience in responding to these problems. In my case it was caused by outdated modules on the Jenkins build. I only called 'npm install' for every build, instead of cleaning first. There was probably a module somewhere in the tree still depending on react 0.13 which was not updated because of lazy requirements. Btw, the link on medium gives a 404.

@gaearon
Copy link
Collaborator

gaearon commented Dec 28, 2015

That happens! Believe me, npm@3.x handles this better (and it has deterministic installs too, so install order shouldn't matter anymore). I fixed the link, thanks.

@jimfb
Copy link
Contributor

jimfb commented Jan 4, 2016

Issue appears to be that user had a duplicate copy of React, as mentioned in the URL given in the warning (https://fb.me/react-refs-must-have-owner). No comments for 7 days, closing.

@jimfb jimfb closed this as completed Jan 4, 2016
@joIivier
Copy link
Author

joIivier commented Jan 5, 2016

That's kind of harsh to close for a week of inactivity at the end of the holiday week ^^, especially since there was no comment to which to answer (I knew I might have multiple react, I asked for a reliable way to find out).
Anyway I tried again, and saw that in our build output the two bundled js files Webpack produces have React.js, even if we had only one react dependency listed by npm -l or find. Normaly our first bundle provides react for the second one, so we alias the 'react' module in the webpack configuration of the second module. But this is apparently ignored by Webpack when building the module so we end up with a second React loaded when we start our second module.
So for those of you that use Webpack, tricky configurations can lead to duplicated files in the build outputs even if the npm dependecies are sane. Search in the build output to find out.

@gaearon
Copy link
Collaborator

gaearon commented Jan 5, 2016

That's kind of harsh to close for a week of inactivity at the end of the holiday week

We are always happy to reopen if this points to a legitimate bug.

Unfortunately your post didn't offer any specific instructions to reproduce so it is not actionable. Closing non-actionable issues helps put focus on the issues that are actionable.

If you find that the issue was not caused by a duplicate React, please let us know, and provide a way to reproduce.

I asked for a reliable way to find out

I usually grep the build output for var React = {. If it's repeated several times, probably I have two Reacts.

Thanks for publishing details of your investigation!

@john-osullivan
Copy link

I know it's been a while since this was closed, but I'm running into this null owner issue and it's breaking my application. Already verified that there aren't two Reacts loaded via:

  • Checking npm ls output
  • Checking Chrome sources as per @gaearon 's blog post
  • Modifying React in one of my components and then checking that the modification was maintained in the React variable used by the new component I'm trying to use (draft-js-plugins)

All of those verified that there's only one React in my application. I've also gone through the entire component tree and refactored things such that all of the components down to the one rendering Editor are created in their parent's render() method. Still getting this bug.

After finding out on StackOverflow that I can check the owner property on this._reactInternalInstance._currentElement, I verified that the _owner was null for the component rendering the Editor. Going up the tree, all of the _owners except for the components which were direct children of data loading HOCs (createContainer from react-meteor-data). All of my classes are defined using ES6 syntax, not sure if that would influence things.

It seemed odd that _owner was always null, but it's an internal thing and I'm not sure how it's supposed to behave. Any tips on why I'm still running into this InvariantViolation even after verifying both listed reasons?

@gaearon
Copy link
Collaborator

gaearon commented Oct 30, 2016

Please file an issue with a minimal example that reproduces it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants