Below is my simple demo app to showcase the issue I am experiencing.
import React from 'react';
import ReactDOM from 'react-dom';
import TestUtils from 'react-addons-test-utils';
var jsdom = require("jsdom").jsdom;
global.document = jsdom("hello world");
global.window = document.defaultView;
TestUtils.renderIntoDocument(<div><div ref="test">test</div></div>);
Basically when I have a ref on any element found in the TestUtils.renderIntoDocument function the following error is being thrown:
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).
at invariant (test/node/index.test.js:108:16)
at Object.addComponentAsRefTo (test/node/index.test.js:60386:48)
at attachRef (test/node/index.test.js:60612:17)
at Object.ReactRef.attachRefs (test/node/index.test.js:60631:6)
at ReactCompositeComponentWrapper.attachRefs (test/node/index.test.js:3156:13)
at CallbackQueue.notifyAll (test/node/index.test.js:28619:23)
at ReactReconcileTransaction.close (test/node/index.test.js:60498:27)
at ReactReconcileTransaction.closeAll (test/node/index.test.js:22529:26)
at ReactReconcileTransaction.perform (test/node/index.test.js:22476:17)
at batchedMountComponentIntoNode (test/node/index.test.js:31777:16)
at ReactDefaultBatchingStrategyTransaction.perform (test/node/index.test.js:22463:21)
at Object.batchedUpdates (test/node/index.test.js:59478:20)
at Object.batchedUpdates (test/node/index.test.js:1095:21)
at Object._renderNewRootComponent (test/node/index.test.js:31940:19)
at Object._renderSubtreeIntoContainer (test/node/index.test.js:32019:33)
at Object.render (test/node/index.test.js:32040:24)
at Object.renderIntoDocument (test/node/index.test.js:60838:22)
at Context.<anonymous> (test/node/index.test.js:35876:53)
I checked if I have multiple copies of React in my project but as you can see from my package.json only React 15.4.1 is installed.
{
"name": "demo-project",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"dependencies": {
"react": "^15.4.1",
"react-addons-test-utils": "^15.4.1",
"react-dom": "^15.4.1"
},
"devDependencies": {
"babel-preset-es2015": "^6.18.0",
"babel-preset-react": "^6.16.0",
"babel-preset-stage-0": "^6.16.0",
"jsdom": "^9.9.1"
}
}
Additionally this is the babelrc
{ "presets": ["react", "stage-0", "es2015"] }
Is this the intended behaviour or a bug since using refs in the context of TestUtils.renderIntoDocument is an important feature.
The error message contains description of the problem:
You might be adding a ref to a component that was not created inside a component's
rendermethod
That's just how string refs work. They only work inside classes (and are discouraged anyway).
Otherwise, where would you expect the ref to be set? How would you read it?
Callback refs don't suffer from that problem. You can use them just fine:
import React from 'react';
import ReactDOM from 'react-dom';
import TestUtils from 'react-addons-test-utils';
var jsdom = require("jsdom").jsdom;
global.document = jsdom("hello world");
global.window = document.defaultView;
var div;
TestUtils.renderIntoDocument(<div><div ref={el => div = el}>test</div></div>);
// You can do something with div now.
I hope this helps!
@gaearon What if the goal is to add a ref to a component that wasn't created a component's render method? For example, a "click-outside" component like this one.
You can use callback refs for this use case, just like that component already does.
That's the nice thing about callback refs: they don't care where element is created.
Most helpful comment
The error message contains description of the problem:
That's just how string refs work. They only work inside classes (and are discouraged anyway).
Otherwise, where would you expect the ref to be set? How would you read it?
Callback refs don't suffer from that problem. You can use them just fine:
I hope this helps!