2017-07-23 139 views
0

我正在尝试使用React与我的Express后端。目前,我使用React作为我的模板语言。React组件只渲染一次

我的意见是.jsx文件。

/* Express */ 
const express = require('express'); 
const app = express(); 
const server = require('http').createServer(app); 
const session = require('express-session'); 
... 
/* Express application parameters */ 
app 
    .set('views', __dirname + '/views') 
    .set('view engine', 'jsx') 
    .engine('jsx', require('express-react-views').createEngine()) 
    .use(bodyParser.urlencoded({ extended: false })) 
    .use(sessionStorage) 
    .use(express.static('public')); 

// Express routing defined in ./routes/index.js 
require('./routes')(app); 

index.js

/* Express routing */ 
module.exports = function (app) { 
    app.get('/subscribe', require('./subscribe').get); 
    app.post('/subscribe', require('./subscribe').post); 
    app.get('/', require('./login').get); 
    app.post('/', require('./login').post); 
    app.all('/userlist', require('./home').all); 
    app.get('/lobby', require('./lobby').get); 
    app.get('/playdario', require('./game').get); 
    app.post('/playdario', require('./game').post); 
    app.all('/logout', require('./logout').all); 
} 

这是我订阅页面路由处理:

subscribe.js

exports.get = (req, res) => { 
    res.render('subscribe', { 'title': 'Subscription' }); 
} 

我想作为一个测试(比如React教程)每秒刷新一个时钟组件。

subscribe.jsx

var React = require('react'); 
    var ReactDOM = require('react-dom'); 
    var DefaultLayout = require('./layouts/default'); 

    class Clock extends React.Component { 
     constructor(props) { 
      super(props); 
      this.state = { date: new Date() }; 
    } 

    componentDidMount() { 
     this.timerID = setInterval(
      () => this.tick(), 
      1000 
     ); 
    } 

    componentWillUnmount() { 
     clearInterval(this.timerID); 
    } 

    tick() { 
     this.setState({ 
      date: new Date() 
     }); 
    } 

    render() { 
     return (
      <DefaultLayout> 
      <div> 
       <h1>Hello, world!</h1> 
       <h2>It is {this.state.date.toLocaleTimeString()}.</h2> 
      </div> 
      </DefaultLayout> 
     ); 
     } 
    } 
    module.exports = Clock; 

所有的我的意见是通过其中包含的HTML标记默认组件组成。

default.jsx

var React = require('react'); 

class DefaultLayout extends React.Component { 
    render() { 
     return (
      <html> 
       <head><title>{this.props.title}</title></head> 
       <body> 
        {this.props.children} 
       </body> 
      </html> 
     ); 
    } 
} 

module.exports = DefaultLayout; 

但问题是,时钟显示只有一次,当我到达的页面。但时钟根本不令人耳目一新。我尝试了另一个例子,用一个改变文本值的按钮,但它不工作...

必须在我的res.render中使用** .jsx *文件吗?当我发送像我在我的项目开始时一样的HTML文件,我没有找到如何通过我的HTML文件发送信息像我可以做的像.twig或.jsx的意见... ...快速发短信

我什么做错了吗?

+0

为什么不试试react-dom的renderToString方法.. –

回答

0

的范围,我不相信express-react-views实际安装的组件。按照其documentation

这是这使得 服务器上反应的组分一Express视图引擎。它呈现静态标记,并且不支持在客户端上安装这些 视图。

因此,没有安装组件,只生成生成的标记。这意味着componentDidMount永远不会被调用,因为组件本身从未在浏览器中实例化。如果你想让React组件与元素进行交互,你需要渲染它在客户端。

+0

但在那种情况下,我怎样才能使用'res.render(...)'渲染我的文件?我必须使用'res.sendFile()'与一个html文件吗?与此,我怎么能通过服务器将变量传递给我的HTML文件?在尝试使用React之前,我使用Twig作为模板,我可以用'res.render()'将一些信息发送到我的视图。这是我正在寻找,但与React ... – MaxHso

+0

你可能不能用ExpressJS做到这一点。相反,您需要从页面内部执行'ReactDOM.render'。你也许可以用'res.render'提供初始内容,但是一旦页面加载完毕,你就需要重新渲染它。 –

+0

那么也许我应该使用像Jade这样的模板引擎,并将我的React组件作为脚本插入到Jade视图中? – MaxHso

0

既然不是重新渲染,我假设tick()没有被触发,因为状态在那里更新。试着做以下几点:

componentDidMount() { 
    this.timerID = setInterval(
     this.tick, 
     1000 
    ); 
} 

componentDidMount() { 
    var self = this 
    this.timerID = setInterval(
     () => self.tick(), 
     1000 
    ); 
} 

因为this不在箭头功能

+0

试过并且没有工作:/它在这里工作:[反应时钟示例](https://codepen.io/gaearon/pen/amqdNA?editors=0010)但他们使用ReactDOM.Render ... – MaxHso