I've been building an isomorphic react app using node-jsx, browserify, reactify, etc. My code runs fine on the server, and components are mounted and rendered correctly. However, the react function doesn't seem to work, for instance, the handleClick function does not recognize alert(), or console.log() never prints out expected result on neither the server nor the client side console. Can anyone identify what's going on here?
UPDATE: Another thing I want to point out is, when I run the server and go to the browser, in the browser console(used chrome dev tool) I typed "window.React", it actually returned the React object. But console.log still doesn't do anything for click handler function.
views/index.ejs
<!doctype html>
<html>
<head>
<title>Shortened URL Generator</title>
<link href='/style.css' rel="stylesheet">
<link href="css/griddle.css" rel="stylesheet" />
</head>
<body>
<h1 id="main-title">Welcome to Shortened URL Generator</h1>
<div id="react-main-mount">
<%- reactOutput %>
</div>
<!-- comment out main.js to see server side only rendering -->
<script src="https://fb.me/react-with-addons-0.14.3.min.js"></script>
<script src="https://fb.me/react-dom-0.14.3.min.js"></script>
<script src="/main.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.6.0/underscore-min.js"></script>
<script src="//fb.me/JSXTransformer-0.12.0.js"></script>
<script type="text/javascript" src="scripts/griddle.js"></script>
</body>
</html>
routes/routes.js
var React = require('react/addons'),
ReactApp = React.createFactory(require('../components/ReactApp'));
module.exports = function(app) {
var storeUrls = {
"fb.com": "facebook.com"
};
app.get('/', function(req, res){
// React.renderToString takes your component
// and generates the markup
var reactHtml = React.renderToString(ReactApp({}));
// Output html rendered by react
// console.log(myAppHtml);
res.render('index.ejs', {reactOutput: reactHtml});
});
app.get('/:routeParam', function(req, res){
});
};
app/components/ReactApp.js
var TableComponent = require('./TableComponent');
var React = require('react/addons');
var urls = require('./url');
var Griddle = React.createFactory(require('griddle-react'));
var ReactApp = React.createClass({
componentDidMount: function () {
console.log("yes");
},
handleClick: function() {
// this.setState({liked: !this.state.liked});
var longUrl = this.refs.inputUrl;
urls.push({
"original url": longUrl,
"shortened url": "/"
})
console.log(longurl);
},
render: function () {
return (
<div>
<div id="form">
<form>
<section>Paste your long url here</section>
<input ref="inputUrl" value={this.props.value} type="text" placeholder="http://...." />
<button onclick={this.handleClick} type="submit" value="Submit">Shorten URL</button>
</form>
</div>
<div id="table-area">
<TableComponent />
</div>
</div>
)
}
});
module.exports = ReactApp;
app/main.js
var React = require('react/addons');
var ReactApp = require('./components/ReactApp');
var TableComponent = require('./components/TableComponent');
var mountNode = document.getElementById('react-main-mount');
var mountTable= document.getElementById('table-area');
React.render(new ReactApp({}), mountNode);
React.render(new TableComponent({}), mountTable);
server.js
var express = require('express'), path = require('path'), app = express(), port = 5000, bodyParser = require('body-parser'); require('node-jsx').install(); // Include static assets. Not advised for production app.use(express.static(path.join(__dirname, 'public'))); // Set view path app.set('views', path.join(__dirname, 'views')); // set up ejs for templating. You can use whatever app.set('view engine', 'ejs'); // Set up Routes for the application require('./app/routes/routes.js')(app); //Route not found -- Set 404 app.get('*', function(req, res) { res.json({ 'route': 'Sorry this page does not exist!' }); }); app.listen(port); console.log('Server is Up and Running at Port : ' + port);
Gulpfile.js
var gulp = require('gulp'); var source = require('vinyl-source-stream'), browserify = require('browserify'); gulp.task('scripts', function(){ return browserify({ transform: [ 'reactify' ], entries: 'app/main.js' }) .bundle() .pipe(source('main.js')) .pipe(gulp.dest('./public/')); }); gulp.task('default', ['scripts']);
It can be a simple modification to your existing code:
Do that for whatever you want make available globally, usually you'll want to do the same for ReactDOM too so you can call render directly in a html file. It's not usually recommended though. You might want to use the standalone downloads from React Downloads.