【问题标题】:React.js: handleSubmit or onClick not triggered when rendered on the server sideReact.js:在服务器端呈现时未触发 handleSubmit 或 onClick
【发布时间】:2014-11-26 20:17:34
【问题描述】:

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

index.js:

module.exports = require('./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;

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:

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;

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

【问题讨论】:

  • 你不能。这不是在服务器上渲染 React 的重点。 onSubmit 等是客户端事件,所以在那里处理它们
  • 我同意,但是在从服务器端呈现客户端页面时如何处理 onSubmit 等...?
  • 您是否在某处渲染组件?您的 app/index.js 包含应用但不呈现它。你需要一个 React.renderComponent(ReactApp(), document.getElementById("wheres-your-container")) 和一个真实的 DOM 元素,组件渲染到该元素中。
  • 从代码中可以看到,我只在renderReactComponent.js中调用了renderComponentToStaticMarkup。所以一切都在服务器端渲染并发送到客户端。

标签: javascript node.js express reactjs


【解决方案1】:

流程是这样的:

  • 客户端请求页面
  • 服务器执行 React.renderComponentToString 并将 html 返回给客户端
  • 此时服务器停止执行任何操作
  • 页面加载到客户端,并运行 React.renderComponent
  • React 注意到带有 reactids 的标记
    • 验证校验和
    • 如果一切顺利,只需添加事件侦听器并等待某事发生
  • 用户可能会提交表单,调用您的 handleSubmit

在handleSubmit 中,如果您想向服务器发送一些数据,您可以使用普通的AJAX/WebSockets/etc 技术来完成。

查看superagent 了解可在浏览器和节点中运行的良好 http 客户端。

【讨论】:

  • 不确定是否理解“在 handleSubmit 中,如果您想向服务器发送一些数据,您可以使用普通的 AJAX/WebSockets/etc 技术来完成”。所以我不需要从服务器端编写handleSubmit 吗?你应该使用什么技术?
  • 例如superagent.post('/api/foo', {author: author, text: text}) 在句柄提交中。有多种抽象方法,例如传递执行此操作的 onCommentSubmit 道具、事件发射器或通量操作。
  • 使用我现在的代码,当点击提交按钮时,console.log() 没有显示任何内容,所以我认为 handleSubmit 没有被触发。当一切都从服务器呈现时,我不知道如何从客户端触发事件。
  • @Herve76 你在客户端调用 React.renderComponent 吗?
  • 不,我只在renderReactComponent.js中调用renderComponentToStaticMarkup。所以一切都在服务器端渲染并发送到客户端
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-26
相关资源
最近更新 更多