Reputation: 113
I'm in the early stages of moving a non-jsx React project to JSX and struggling a bit to get it working.
I've managed to create a simple JSX component working when created from a, index.jsx file, but I'm trying to integate with existing code, and I'd like to start by combining 'legacy' React classes with my new JSX classes.
My Dropdown.jsx code looks like this:
class Dropdown extends React.Component {
constructor(props) {
super(props);
this.state = {
value: null,
};
}
render() {
return <div>
<select name="carlist" form="carform">
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="opel">Opel</option>
<option value="audi">Audi</option>
</select>
</div>;
}
}
export default Dropdown;
The html file I'm trying to instantiate the React component from is as follows (this is how most of my legacy code looks )
<!DOCTYPE html>
<html lang="en" xmlns="">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<div id="app"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react-dom.js"></script>
<script src="dist/react-bundle.js"></script>
<script type="application/javascript">
ReactDOM.render(
React.createElement(Dropdown, {}, null),
document.getElementById('app')
);
</script>
</body>
</html>`
And my webpack.config.js file is as follows:
var path = require('path') ;
module.exports = {
entry: {
react: [ './src/Dropdown.jsx' ]
},
output: {
library: "Dropdown",
libraryTarget: "umd",
path: path.join( __dirname, 'dist' ),
filename: '[name]-bundle.js'
},
devtool: 'source-map',
module: {
loaders:
[
{
test: /\.js$/,
exclude: /node_modules/,
loaders: [
'babel-loader'
]
},
{
test: /\.jsx$/,
exclude: /node_modules/,
loaders: [
'babel-loader'
]
}
]
}
};
I've done a fair bit of research to try to resolve this, the last of which was adding the 'library' and 'libraryTarget' settings to the config file.
The script SEEMS to be recognising the Dropdown class ( I.e. it's not failing with a class not found type error ) but I'm getting the folloiwng instead:
Warning: React.createElement: type should not be null, undefined, boolean, or number.
It should be a string (for DOM elements) or a ReactClass (for composite components).
I know this class works when instantiated from an index.jsx file
import React from 'react';
import ReactDOM from 'react-dom';
import Dropdown from './Dropdown';
ReactDOM.render(
<Dropdown />,
document.getElementById('app')
);
export default Dropdown ;
Am I approaching this migration in the wrong way? - I would have thought I could mix and match old React code with JSX output...?
Many thanks in advance
Upvotes: 0
Views: 426
Reputation: 600
The thing with Webpack is that the classes you have created are properly encapsulated from the outside world. the error you are getting
Warning: React.createElement: type should not be null, undefined, boolean, or number.
It should be a string (for DOM elements) or a ReactClass (for composite components).
is an error with react when React cannot find the class declaration anywhere. while I would suggest you follow the proper way and instantiate it in an index.jsx file, you can still make that work by doing this hack in Dropdown.jsx
window.Dropdown = Dropdown
this would make sure that your external non webpack compiled javascript can see the dropdown class. but this is bad pactice and I would really suggest you stick with the index.jsx file as it protects you from exposing your classes and libraries from the global namespace and its a best practice.
Upvotes: 1