66

I have a simple react component with a form in it:

var AddAppts = React.createClass({
    handleClick: function() {
        var title = this.refs.title.getDOMNode().value;
        ....

        var appt = {
            heading: title
            ...
        }

        CalendarActions.addAppointment(appt);
    },

    render: function() {
        return (
            <div>
                <label>Description</label>
                <input ref="title"></input>
                ...
            </div>
        );
    }
});
module.exports = AddAppts;

I am trying to render this component in another react component:

  var AddAppt = require('./AddAppts');

  render: function() {
    return (
      <div>
        <AddAppt />
      </div>
    );
  }

but I get this error:

 Uncaught Error: Invariant Violation: addComponentAsRefTo(...): Only a ReactOwner can have refs. This usually means that you're trying to add a ref to a component that doesn't have an owner (that is, was not created inside of another component's `render` method). Try rendering this component inside of a new top-level component which will hold the ref.

I have googled it, but cannot figure out what I need to do to fix this issue.

Gajus
  • 69,002
  • 70
  • 275
  • 438
jhamm
  • 24,124
  • 39
  • 105
  • 179

12 Answers12

55

This is FYI for people using react and redux-devtools who are getting OP's message. Your structure looks like

project
  client
  node_modules
    react
    redux-devtools
      node_modules
        react

The code in client will require the first react module; that in redux-devtools will require the other react. The react module keeps state and assumes it has all the state.

You get the OP's message because your state is split between the 2 react modules. This situation is what I believe @asbjornenge refers to.

I was bundling the client code with webpack, so I used that to handle the issue. You can force all require and import to always use the first react by adding the following to webpack.config.js

module.exports = {
  ...
  resolve: {
    alias: {
      'react': path.join(__dirname, 'node_modules', 'react')
    },
    extensions: ['', '.js']
  },
  ...
);

I have not looked into what I would need to do if the situation occurred with unbundled code running on node.

JohnSz
  • 2,049
  • 18
  • 17
42

I encountered this error when a component module I was using had it's own react dependency installed. So I was using multiple versions of React.

Make sure NOT to list react under dependencies in your package.json.
This is why we have peerDependencies ;-)

Philipp Kyeck
  • 18,402
  • 15
  • 86
  • 123
asbjornenge
  • 1,209
  • 13
  • 16
  • Ah! Thanks for this. I was accidentally compiling two versions of React in a test and coming up with this error. I'd never have found it by myself. Rookie mistake! – Malabar Front May 09 '15 at 19:20
  • 6
    Aren't peer dependencies being removed in NPM 3.0? What then? – JohnSz Sep 07 '15 at 17:03
  • My problem is the order of the loading script. I load react-with-addons.js before react-dom.js. And the problem appeared. I doubt that there are some feature in react-with-addons.js :) – Ni Xiaoni Oct 25 '15 at 04:51
  • 1
    @JohnSz peerDependencies are not being removed, they will just warn instead of auto-installing. See https://github.com/npm/npm/issues/6565#issuecomment-74971689. – SystemParadox Jan 21 '16 at 16:13
16

Just in case. Be aware of the React module name you are using (it is case-sensitive). I've got the same error when by coincidence I tried to require React dependency with different names in two separate modules.

//module1.js
var React = require('react');
...

//module2.js
var React = require('React');
....

It works and even renders something but the Only a ReactOwner can have refs... error appears.

kreig
  • 990
  • 11
  • 18
  • 1
    You just save me! I've been digging around for 20 minutes going crazy. I read this and looked down at my editor. Sure enough, a big "require('React')" was staring right back at me. – AndrewJM Feb 19 '16 at 18:39
3

Rearranging the script resolved the issue.

Wrong.

<script src="./lib/react.js"></script>
<script src="./lib/react-dom.js"></script>
<script src="./lib/react-with-addons.js"></script>

Correct

<script src="./lib/react.js"></script>
<script src="./lib/react-with-addons.js"></script>
<script src="./lib/react-dom.js"></script>

Reference https://github.com/gcanti/tcomb-form/issues/107#issuecomment-150891680

VenomVendor
  • 15,064
  • 13
  • 65
  • 96
  • 3
    Is including both `react` and `react-with-addons` necessary? Does not the latter include all the code of the former? – Fabio Iotti Mar 02 '16 at 06:58
2

I saw this error while developing a react module that was linked to a test project using npm link. Switching to a regular dependency solved the problem.

It seems that React doesn't like npm link.

François Zaninotto
  • 7,068
  • 2
  • 35
  • 56
1

There is another situation.

I set the React as external library in the webpack.config.js and import react.js from cdnjs.

externals: {
  'react': 'React'
}

When I using an ui library depend on React,such as material-ui,react-bootstrap,this issue occurred.

joe.rong
  • 73
  • 3
0

am writing with my old pen. make sure in your project root package.json move react dependency as early as possible. still you are getting issue? & if you are using npm modules and grunt task, you can add below clean task to remove inner components react(duplicates).

clean: { react : ['node_modules/**/react','!node_modules/react'] },

Manivannan
  • 3,074
  • 3
  • 21
  • 32
0

I saw this error after I moved my package.json file up a level, so I had 2 node_modules directories in my project (one in ./node_modules and another in ./web/node_modules). Removing the old directory fixed the problem.

ty.
  • 10,924
  • 9
  • 52
  • 71
0

For me the reason for the same problem was that I've imported the ReactDom globally, as a property of the window object, like this:

import ReactDOM from 'react-dom'
window.ReactDOM = ReactDOM

removing window.ReactDOM = ReactDOM fixed the problem.

Dmitry Sokurenko
  • 6,042
  • 4
  • 32
  • 53
0

Similar to this answer, I was seeing this error while using a separate module that I had been developing in a separate directory using yarn link.

The solution was to run yarn unlink module-name in my project's working directory. I then removed node_modules and ran yarn upgrade module-name and yarn for good measure.

Community
  • 1
  • 1
taylor
  • 1,568
  • 1
  • 10
  • 11
0

Instead of

<input ref="title"></input>

Try this

<input ref={(title) => this.title = title}></input>
0

None of the given solutions worked for me, though they certainly helped show me where to look.

For some reason my project has two node_modules folders - one in the root directory and one a level up. I'm new to React so I don't know if this is normal or what. I'm just going with what Visual Studio gave me when I started a new project.

Anyway, I knew which module was causing the problem, and it happened to only exist in one of the node_modules folders.

I moved the problem module over to the other node_modules folder. Problem solved.

Stuart Aitken
  • 949
  • 1
  • 13
  • 30