Javascript React.js:handleSubmit或onClick在服务器端渲染时未触发

Javascript React.js:handleSubmit或onClick在服务器端渲染时未触发,javascript,node.js,express,reactjs,Javascript,Node.js,Express,Reactjs,我在服务器端渲染所有内容时遇到问题,并触发了handleSubmit。以下是源代码: index.js: module.exports = require('./app/server'); app/server/index.js: 'use strict'; var env = process.env.NODE_ENV || 'development'; var express = require('express'); var http = require('http'); var app

我在服务器端渲染所有内容时遇到问题,并触发了handleSubmit。以下是源代码:

index.js:

module.exports = require('./app/server');
app/server/index.js:

'use strict';

var env = process.env.NODE_ENV || 'development';
var express = require('express');
var http = require('http');
var app = express();

app.set('state', {});


// Inject Config
require('../config/server')[env](app, express);

// Inject component rendering
require('node-jsx').install({extension: '.jsx'});
app.use(require('../../lib/renderReactComponent')(app));

// Start server
var server = http.createServer(app);
return server.listen(app.get('port'), function() {
  return console.log('Listening on port ' + app.get('port') + ', Env: ' + app.settings.env);
});

module.exports = app;
var ReactApp = require('./components/app');
module.exports = ReactApp;
lib/renderReactComponent.js:

var ReactApp = require('../app');
var React = require('react');
var path = require('path');
var url = require('url');

module.exports = function(app) {
  return function(req, res, next) {
    try {
      var path = url.parse(req.url).pathname;
      res.send(React.renderComponentToStaticMarkup(ReactApp({path: path, state: app.get('state')})));
    } catch(err) {
      return next(err)
    }
  }
}
app/index.js:

'use strict';

var env = process.env.NODE_ENV || 'development';
var express = require('express');
var http = require('http');
var app = express();

app.set('state', {});


// Inject Config
require('../config/server')[env](app, express);

// Inject component rendering
require('node-jsx').install({extension: '.jsx'});
app.use(require('../../lib/renderReactComponent')(app));

// Start server
var server = http.createServer(app);
return server.listen(app.get('port'), function() {
  return console.log('Listening on port ' + app.get('port') + ', Env: ' + app.settings.env);
});

module.exports = app;
var ReactApp = require('./components/app');
module.exports = ReactApp;
app/components/app.js:

/**
 * @jsx React.DOM
 */

var React = require('react');
var ReactRouter = require('react-router-component');

var App = React.createClass({

  propTypes: {state: React.PropTypes.object.isRequired},

  getInitialState: function() {
    return {items: [], text: ''};
  },

  handleSubmit: function () {
    console.log("handleSubmit triggered!");
    var $author         = this.refs.author.getDOMNode(),
        $text           = this.refs.text.getDOMNode(),
        author          = $author.value.trim(),
        text            = $text.value.trim();

    if(!author || !text) {
        return false;
    }

    if(this.props.onCommentSubmit) {
        this.props.onCommentSubmit({ author: author, text: text });
    }

    $author.value = '';
    $text.value = '';

    return false;
  },

  render: function() {
    return (
      <html>
            <form className="commentForm" onSubmit={this.handleSubmit}>
                <input type="text" ref="author" placeholder="Your name"/>
                <input type="text" ref="text" placeholder="Say Something ..."/>
                <input type="submit" value="Post"/>
            </form>
      </html>
    );
  }
});
module.exports = App;
/**
*@jsx React.DOM
*/
var React=要求('React');
var ReactRouter=require('react-router-component');
var App=React.createClass({
propTypes:{state:React.propTypes.object.isRequired},
getInitialState:函数(){
返回{items:[],文本:'};
},
handleSubmit:函数(){
log(“handleSubmit已触发!”);
var$author=this.refs.author.getDOMNode(),
$text=this.refs.text.getDOMNode(),
author=$author.value.trim(),
text=$text.value.trim();
如果(!author | |!text){
返回false;
}
if(this.props.onCommentSubmit){
this.props.onCommentSubmit({作者:作者,文本:文本});
}
$author.value='';
$text.value='';
返回false;
},
render:function(){
返回(
);
}
});
module.exports=App;

这段代码没有给我一个错误,但是handleSubmit没有被触发。我认为这是因为它不是由服务器端渲染的。在尝试从服务器端呈现页面时,如何触发表单事件handleSubmit?

流程如下:

  • 客户端请求一个页面
  • 服务器执行React.renderComponentToString并将html返回给客户端
  • 此时服务器停止任何操作
  • 页面加载到客户端,并运行React.renderComponent
  • React注意到带有ReactID的标记
    • 验证校验和
    • 如果一切正常,只需添加事件监听器并等待事件发生
  • 用户可能会提交表单,调用handleSubmit
在handleSubmit中,如果您想向服务器发送一些数据,可以使用普通的AJAX/WebSockets/etc技术


查看在浏览器和节点中工作的良好http客户端。

您不能。这不是在服务器上呈现React的要点
onSubmit
etc是客户端事件,因此在那里处理它们我同意,但我如何处理onSubmit等。。。从服务器端呈现客户端页面时,是否在某个地方呈现组件?您的app/index.js包含该应用程序,但不呈现它。您需要一个
React.renderComponent(ReactApp(),document.getElementById(“您的容器在哪里”)
,其中包含一个真实的DOM元素,组件将呈现到其中。正如您在代码中看到的,我只在renderReactComponent.js中调用renderComponentToStaticMarkup。因此,所有内容都在服务器端呈现并发送到客户端。不确定是否理解“在handleSubmit中,如果您想向服务器发送一些数据,可以使用普通的AJAX/WebSockets/etc技术”。所以我不需要从服务器端编写handleSubmit?您应该使用什么技术?例如handleSubmit中的
superagent.post('/api/foo',{author:author,text:text})
。有多种方法可以抽象它,例如,传递执行此操作的onCommentSubmit道具、事件发射器或flux操作。根据我目前的代码,当单击submit按钮时,console.log()不会显示任何内容,因此我认为handleSubmit不会被触发。当从服务器呈现所有内容时,我不知道如何从客户端触发事件。@Herve76是否在客户端调用React.renderComponent?不,我只在renderReactComponent.js中调用renderComponentToStaticMarkup。因此,所有内容都在服务器端呈现并发送到客户端