Javascript 同构React-如何使React功能成为窗口对象的一部分

Javascript 同构React-如何使React功能成为窗口对象的一部分,javascript,gulp,browserify,isomorphic-javascript,reactify,Javascript,Gulp,Browserify,Isomorphic Javascript,Reactify,我一直在使用node jsx、browserify、reactify等构建一个同构的react应用程序。我的代码在服务器上运行良好,组件安装和呈现正确。但是,react函数似乎不起作用,例如,handleClick函数不识别alert(),或者console.log()从未在服务器或客户端控制台上打印出预期结果。有人能确定这里发生了什么吗 var express = require('express'), path = require('path'), app = express(), po

我一直在使用node jsx、browserify、reactify等构建一个同构的react应用程序。我的代码在服务器上运行良好,组件安装和呈现正确。但是,react函数似乎不起作用,例如,handleClick函数不识别alert(),或者console.log()从未在服务器或客户端控制台上打印出预期结果。有人能确定这里发生了什么吗

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);
更新:我想指出的另一件事是,当我运行服务器并进入浏览器时,在浏览器控制台(使用chrome开发工具)中键入“window.React”,它实际上返回了React对象。但是console.log仍然不能为click处理程序函数做任何事情

视图/索引.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>
    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){

    });

};
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;
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);
app/components/ReactApp.js

<!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>
    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){

    });

};
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;
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

Gulpfile.js

<!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>
    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){

    });

};
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;
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);
var gulp=需要(“gulp”); var source=require('venyly-source-stream'), browserify=要求(“browserify”); gulp.task('scripts',function()){ 返回浏览器化({ 转换:['reactify'], 条目:“app/main.js” }) .bundle() .pipe(源('main.js')) .pipe(""/公共");; }); gulp.task('default',['scripts']);
它可以是对现有代码的简单修改:

React.render(new ReactApp({}), mountNode);

如果希望全局可用,通常也希望对ReactDOM执行相同的操作,以便可以在html文件中直接调用render。但通常不推荐使用。您可能希望使用独立的下载,从.getElementById('react-main-mount')返回null


您应该做的是在结束标记
之前包含脚本,或者在结束标记之后运行
ReactDOM.render

因此我意识到它与main.js文件中的React.render有关。而不是

React.render(<ReactApp/>, document.getElementById('react-main-mount'));
应该是

React.render(,document.getElementById('React-main-mount');
在这种情况下,不需要呈现TableComponent,也需要React而不使用插件


现在可以了。谢谢大家的帮助

你的看法如何?脚本是否包含在
中或
末尾?您好,请查看我的更新视图和路线您是否检查了浏览器控制台?你有什么错误吗?谢谢你的建议!我尝试了您的解决方案,但当我尝试运行服务器时,它抛出“ReferenceError:window is not defined”(引用错误:未定义窗口)检查更新的代码示例。希望这能解决你的问题。我也试过了,但看起来它无法识别窗口对象。它仍然抛出参考错误嗨,谢谢你的建议。我的脚本标记包含在结束标记之前,但不确定“在DOMContentLoaded之后运行ReactDOM.render”是什么意思,您介意再解释一下吗?在这种情况下,这个答案可能不相关。阅读我链接到的文章。在进行前端开发时,您应该了解它的一切。