I use webpack and have a simple react application, where I want to use react-autosuggest component. When I want to use this component in my application I get 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.
index.jsx
var React = require('react')
var Autosuggest = require('react-autosuggest')
var autoCompleteItems = ['item1', 'item2', 'item3', 'item4', 'item5', 'item6'];
function getSuggestions(input, callback) {
const escapedInput = utils.escapeRegexCharacters(input.trim());
const lowercasedInput = input.trim().toLowerCase();
const suburbMatchRegex = new RegExp('\\b' + escapedInput, 'i');
const suggestions = autoCompleteItems
.filter( suburbObj => suburbMatchRegex.test(suburbObj.suburb) )
.sort( (suburbObj1, suburbObj2) =>
suburbObj1.suburb.toLowerCase().indexOf(lowercasedInput) -
suburbObj2.suburb.toLowerCase().indexOf(lowercasedInput)
)
.slice(0, 7)
.map( suburbObj => suburbObj.suburb );
setTimeout(() => callback(null, suggestions), 300);
}
class SuggestWrapper extends React.Component {
render () {
var inputId = 'input-example';
const inputAttributes = {
id: inputId,
className: "form-control",
defaultValue: '',
placeholder: this.props.propertyName
};
return (
<Autosuggest suggestions={getSuggestions}
inputAttributes={inputAttributes}
ref={ () => { document.getElementById(inputId).focus(); } } />
);
}
}
class App extends React.Component {
render () {
return (
<div>
<SuggestWrapper />
</div>
);
}
}
React.render(<App />, document.getElementById('content'));
package.json
{
"name": "react_modules",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "npm run serve | npm run dev",
"serve": "./node_modules/.bin/http-server -p 8080",
"dev": "webpack-dev-server -d --progress --colors --port 8090"
},
"author": "",
"license": "ISC",
"devDependencies": {
"babel-core": "^5.8.24",
"babel-loader": "^5.3.2",
"bootstrap": "^3.3.5",
"bower-webpack-plugin": "^0.1.8",
"css-loader": "^0.18.0",
"events": "^1.0.2",
"extract-text-webpack-plugin": "^0.8.2",
"file-loader": "^0.8.4",
"http-server": "^0.8.0",
"jquery": "^2.1.4",
"jquery-ui": "^1.10.5",
"less": "^2.5.1",
"less-loader": "^2.2.0",
"lodash": "^3.10.1",
"node-sass": "^3.3.2",
"object-assign": "^4.0.1",
"path": "^0.11.14",
"react": "^0.13.3",
"react-autosuggest": "^1.18.3",
"react-hot-loader": "^1.3.0",
"sass-loader": "^2.0.1",
"style-loader": "^0.12.3",
"svg-sprite-loader": "0.0.3",
"url-loader": "^0.5.6",
"webpack": "^1.12.1",
"webpack-dev-server": "^1.10.1"
}
}
webpack.config.js
const BowerWebpackPlugin = require("bower-webpack-plugin");
module.exports = {
entry: './src/index.jsx',
output: {
filename: 'bundle.js',
sourceMapFilename: "[file].map",
publicPath: 'http://localhost:8090/assets'
},
debug: true,
devtool: 'inline-source-map',
module: {
loaders: [{
test: /\.js[x]?$/,
loaders: ['react-hot', 'babel'],
exclude: /node_modules/
}, {
test: /\.scss$/,
loaders: ['style', 'css?sourceMap', 'sass?sourceMap']
}, {
test: /\.less$/,
loaders: ['style', 'css?sourceMap', 'less?sourceMap']
}, {
test: /\.css$/,
loaders: ['style', 'css']
}, {
test: /\.woff$/,
loader: "url-loader?limit=10000&mimetype=application/font-woff"
}, {
test: /\.woff2$/,
loader: "url-loader?limit=10000&mimetype=application/font-woff2"
}, {
test: /\.(eot|ttf|svg|gif|png)$/,
loader: "file-loader"
}]
},
plugins: [
new BowerWebpackPlugin()
],
externals: {
'react': 'React'
},
resolve: {
extensions: ['', '.js', '.jsx']
}
}
index.html
<!DOCTYPE html>
<html>
<head>
<title>App</title>
<!-- include react -->
<script src="./node_modules/react/dist/react-with-addons.js"></script>
</head>
<body>
<div id="content">
<!-- this is where the root react component will get rendered -->
</div>
<!-- include the webpack-dev-server script so our scripts get reloaded when we make a change -->
<!-- we'll run the webpack dev server on port 8090, so make sure it is correct -->
<script src="http://localhost:8090/webpack-dev-server.js"></script>
<!-- include the bundle that contains all our scripts, produced by webpack -->
<!-- the bundle is served by the webpack-dev-server, so serve it also from localhost:8090 -->
<script type="text/javascript" src="http://localhost:8090/assets/bundle.js"></script>
</body>
</html>
I tried to follow this post and add:
alias: {
'react': path.join(__dirname, 'node_modules', 'react')
},
but it didn't help.