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

Invariant Violation: addComponentAsRefTo(...): Only a ReactOwner can have refs #606

Closed
mockdeep opened this issue Nov 19, 2015 · 34 comments
Closed

Comments

@mockdeep
Copy link

Trying to integrate react-select into our application and we're seeing the following error. There may be something in our workflow that is causing it. We're using ReactDOM to render react components into our 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).

An example:

// other code
function init() {
  model.on('change', renderRecipientDisplay);
}

function logChange(val) { console.log("Selected: " + val); }

function renderRecipientDisplay() {
  var ReactSelect = require('react-select');
  var options = [{ value: 'one', label: 'One' }, { value: 'two', label: 'Two' }];

  ReactDOM.render(
    (
      <ReactSelect name="form-field-name" value="one" options={options} onChange={logChange} />
    ),
    $el.find('.routing-recipient-display')[0]
  );
}
@albertoclarit
Copy link

I encounter this problem few days ago with the same message as you got from the console...

The reason was React module was loaded twice. I had an html file that contains

<script type="text/javascript" src="<@spring.url "/react/react.min.js"/>"></script>
<script type="text/javascript" src="<@spring.url "/react/react-dom.min.js"/>"></script>
<script type="text/javascript" src="<@spring.url "/react/components/compiled/subcontract.js"/>"></script>

and subcontract.js is generated by webpack.
The problem was one of the modules inside subcontract has a dependency to React module and webpack has also bundled that into the compiled subcontract.js. Therefore two React module was loaded in the page...

@mockdeep
Copy link
Author

Yeah, I was trying to explore the same possibility. How did you end up resolving it? Right now we have a version required in our application code, but it looks like react-select is maybe pulling in another copy for some reason.

@jeromegn
Copy link

I'm getting the same error, with no indication that I'm loading React more than once.

I'm trying to render <Select /> within one of my other components. Apparently that's not possible since this is using refs. I'm not entirely sure why yet.

This project has figured if they removed refs, it might be easier to nest this component inside another component: https://github.com/bebraw/reactabular/issues/41

@radar
Copy link

radar commented Nov 23, 2015

I'm also getting this error. I will attempt to reproduce this issue in a new application.

@jeromegn
Copy link

In the end, it really was React being loaded too many times.

I don't believe the browserify shimming applies to installed node modules. Therefore instead of using the global React, it imports another one. I don't feel like this is an issue with react-select. At least for me, it's an issue with browserify loading multiple copies of the same library (React) when requested more than once by other modules.

If I assign React to global.React and remove all requires of it in the react-select and react-input-autosize files, it works just fine.

@mockdeep
Copy link
Author

Is it possible react-select is defining its own require in spite of browserify, so it doesn't have the same reference?

@mockdeep
Copy link
Author

Dug in a little deeper and there are two versions of react in my node_modules directory:

node_modules/react/

and

node_modules/react-select/node_modules/react/

I modified the ReactVersion file of each of these and discovered that my application is pulling in the top one, but react-select is pulling in the bottom. What next?

@mockdeep
Copy link
Author

I updated npm to 3.4.1 which flattens dependencies and I'm still seeing this issue. I've confirmed that both react-select and my application are both using the same copy of react.

@albertoclarit
Copy link

try switching to webpack.. i did not encounter the problem anymore after i remove the

<script type="text/javascript" src="<@spring.url "/react/react.min.js"/>"></script>
<script type="text/javascript" src="<@spring.url "/react/react-dom.min.js"/>"></script>

@hpaul
Copy link

hpaul commented Dec 8, 2015

I encounter same problem, but it's not caused by duplicate react dependecy.

I'm Implementing a separate form library and React say that I can't use refs outside of ReactOwner.
So, I can't include a react component which use refs. But if I include react-select in main application it works.

This is how I wrap react-select:

import React, { PropTypes, Component } from 'react';
import Select from 'react-select';
import styles from './select.scss';
import withStyles from '../../decorators/withStyles';
import {connect} from 'react-redux';
import { setValue } from '../../actions/validation';

@withStyles(styles)
class Container extends Component {

  render() {
    return (
      <div>
        <Select ref="selectbox" {...this.props} />
      </div>
    );
  }
}

export default connect(state => ({
  validation: state.validation,
}))(Container);

It's a select component.
screen shot 2015-12-08 at 18 29 02

@nburwell
Copy link

I am running into this issue too, using browserify-shim with the following external config:

module.exports = {
  "react": { exports: "global:React" },
  "react-dom": { exports: "global:ReactDOM" }
};

(As we had to load React on the page itself because other code on the page outside of the component I am trying to build relies on it). That was all working fine, until we did the following:

var React = require('react');
var Select = require('react-select');  // <--------- this ends up pulling in a second version of react rather than using the shim / global

module.exports = React.createClass({
  render: function() {
    var options = [
      { value: 'one', label: 'One' },
      { value: 'two', label: 'Two' }
    ];

    return(
      <Select options={options}></Select>
    );
  }
});

Has anyone resolved or worked around this issue while still using browserify-shim for React? It seems like browserify should be using the same configuration when resolving the requires down in a node_module package.

@mockdeep
Copy link
Author

We ended up giving up on react-select for the time being.

@davidmilo
Copy link

Anyone figured this out? I am still having same issue.

@davidmilo
Copy link

I tried with a simple component (cjsx syntax)

React = require('react')
Select = require('react-select')

@Test = React.createClass
  render: ->
    <div>
      <h1>Does it work?</h1>
      <Select />
    </div>

module.exports = @Test

But I still get the same error. I tried to remove all require('react') and require('react-dom') from react-select but error persists. I think it is related to the usage of refs in your code maybe? I tried both versions 0.9.1 and 1.0.0-beta9.

I will have to give up on react-select same as @mockdeep unless someone has some suggestions?

@c9s
Copy link

c9s commented Apr 30, 2016

I guess it's caused by the refs used in the methods of the mixins.

@cubbuk
Copy link

cubbuk commented May 4, 2016

Just for an information, I receive this error when I add a new dependency to the project. If I delete node_modules and reinstall all the dependencies the error does not occur again.

@aneeshpu
Copy link

same as cubbuk. I deleted node_modules and reinstalled all dependencies. The error went away

@kesha-antonov
Copy link

Reinstalling node_modules unfortunately didn't work for me. Please fix this

@kesha-antonov
Copy link

Ok, soled it. Got separate file with React. Stop requiring packages locally and require them with npm (from node_modules) solved it.

@salman-virk
Copy link

@kesha-antonov I am having the same problem. I deleted node_modules and reinstalled by running npm install. But, I still see the error. What do you mean by 'Stop requiring locally'?

@kesha-antonov
Copy link

kesha-antonov commented Jul 13, 2016

I had file ".../my_directory/react.js"

And in package.json

"browser": {
   "react": ".../my_directory/react.js",
   ...

I removed that line from "browser" block and also "react-dom", "formsy-react" and did npm install react react-dom formsy-react --save

And then I succeed
@salman-virk

@ttrinh
Copy link

ttrinh commented Aug 14, 2016

More solutions here in case anyone needs
https://gist.github.com/jimfb/4faa6cbfb1ef476bd105

@iainbeeston
Copy link

For me this issue was caused by using turbolinks with react-select. I didn't have time to get to figure out exactly what turbolinks was doing to cause the issue but (based on the other comments in this thread) I suspect it was reloading react when I changed pages. Removing turbolinks stopped this from happening (although there probably is a way to successfully use react-select alongside turbolinks).

@vkbr
Copy link

vkbr commented Sep 1, 2016

I found a hacky solution.

In the dependent component instead of just exporting the React component I am exporting a function which returns the React component

select.jsx

module.exports = function (React) {
    var Select = React.createClass({
        render: function () {
            return (
                <div className="select">
                    <select ref="select"></select>
                </div>
            );
        }
    });

    return Select;
};

And when importing do something like this:

someFile.jsx

import React from 'react';
var Select = require('select')(React);

This would prevent the child component from having it's own React dependency.

@sdoomz
Copy link

sdoomz commented Sep 21, 2016

I've installed react-select 1.0.0-rc.1 and it works fine for me. Version 1.0.0-rc.2 still cause 'Invariant Violation' error.

@ZLester
Copy link

ZLester commented Oct 31, 2016

@nburwell – Same setup as you and I'm running into the same issue. Did you ever discover a fix for this?

@PendletonJones
Copy link

We had this same issue but found a fix that has not been mentioned thus far. In our webpack setup we had a DLLs config with several entry points that was responsible for outputting 5-6 DLLs to be referenced in the main config. 'react-select' was in one and 'react-modal' was in another. Upon further inspection I realized that each of the DLL bundles was getting it's own copy of react. The bug only surfaced when a react-select box was nested inside of a react modal, but both libraries worked independently.

Solution was to have a multi-layered dll build process where a dll bundle containing just react and friends is created first, then referenced by the "level 2" dll bundles that contain things like react-select, then all the resulting dll bundles are referenced by the main build file.

Use the webpack analyze tool to inspect the stats from your bundles, it should provide some insight into how and why webpack is inserting multiple bundles.

Another solution that has worked in the past for me with the 'multiple copies of react' issue is to use the resolve section of the webpack config to point to a particular single copy of react.

@seanriordan08
Copy link

I hit this when implementing browserify-rails. Defining const ReactCSSTransitionGroup = React.addons.CSSTransitionGroup; in your component while also declaring import ReactCSSTransitionGroup from "react-addons-css-transition-group" will throw it.

@ritikama
Copy link

ritikama commented May 4, 2017

I had
<script src="https://unpkg.com/[email protected]/dist/react.js"></script>

<script src="https://unpkg.com/[email protected]/dist/react-dom.js"></script>

in my HTML file. I deleted these lines and it worked

@marcellodesales
Copy link

marcellodesales commented May 13, 2017

Should I give up???

I spent a couple of hours building this use case in isolation and after that, I decided the release a reusable component. However, after hours and hours and days trying to get this to work I'm finally in the step of making a decision...

I based my example on the sample from http://jedwatson.github.io/react-select/.

  • QUESTION: How can I use this component, build a shared/isolated component, and still reuse it in my main application without this error?

Running in isolation: Works

screen shot 2017-05-13 at 1 19 26 am

Running as a Shared Component

The component above then was placed in an isolated NPM Module/component and published to our private NPM registry. Then, when trying to see the component, I get the following error...

screen shot 2017-05-13 at 1 18 38 am

Running as a Share Library: Arrows keys partially work...

As a consequence, the UI can't render the properties right, but I can still use the up-down arrows to select my options, but without the nice UI experience...

screen shot 2017-05-13 at 1 18 49 am

Still work although it does not render properly..

screen shot 2017-05-13 at 1 27 11 am

Events don't work anymore

screen shot 2017-05-13 at 1 27 58 am

No duplicate react Dependency

$ npm ls | grep react@
npm info it worked if it ends with ok
npm info using [email protected]
npm info using [email protected]
│ │ ├─┬ [email protected]
│ └─┬ [email protected]
├─┬ [email protected]
├─┬ [email protected]
npm info ok

@kutyel
Copy link

kutyel commented May 15, 2017

I had this issue for weeks and just installed the latest version of react select 1.0.0-rc.4 and now everything works! 🎉 🎉 🎉 Huge thanks, @JedWatson!

@warrenca
Copy link

After weeks of digging, the root cause of my issue is with http://fb.me/react-warning-keys. Had a lot of trial and error by removing codes/debugging but Invariant Violation: addComponentAsRefTo(...): Only a ReactOwner can have refs was solved by fixing react-warning-keys. Just sharing as this might help other people.

@Sarkany-Adrian
Copy link

@cubbuk's suggestion worked for me. The way I ended up with 2 copies of react was by debugging and rebuilding the react-select within node_modules of my project, in order to rebuild I ran npm i in /node_modules/react-select which installed a new copy of react. Hope this is helpful for anyone else.

@JedWatson
Copy link
Owner

I'm going to close this, as it's not really a react-select issue (and almost always related to having two copies of react loaded). Some great causes and solutions above 👍

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