2016-05-17 9 views
2

react-routerと連携して、反応アプリケーションのサーバーサイド/同形レンダリングを試行しています。renderPropsはサーバー側で定義されていません/ React-Router + Node/Express.jsの同形レンダリング

マイroute.js

import React from 'react'; 
import { Route } from 'react-router'; 

import Test from './components/test'; 

export default (
    <Route path="/test" component={ Test }> 
    </Route> 
); 

マイserver.js

'use strict'; 

require('babel-core/register') 

var path = require('path'); 
var express = require('express'); 
var logger = require('morgan'); 
var compression = require('compression'); 
var http = require('http'); 

var ReactDOM = require('react-dom/server'); 
var Router = require('react-router'); 
var match = Router.match; 
var RoutingContext = Router.RoutingContext; 
var routes = require('./src/routes'); 


var app = express(); 
var server; 
var PORT = process.env.PORT || 3000 


app.use(logger('dev')); 
app.use(compression()); 

// Set path to public assets 
app.use(express.static(path.join(__dirname, 'public'))); 

app.get('*', function(req, res) { 

    console.log('URL: ', req.url); 
    console.log('Routes: ', routes); 

    match({ routes: routes, location: req.url }, (error, redirectLocation, renderProps) => { 
    console.log('Render Props: ', renderProps) 
    if (error) { 
     res.status(500).send(error.message) 
    } else if (redirectLocation) { 
     res.redirect(302, redirectLocation.pathname + redirectLocation.search); 
    } else if (renderProps) { 
     res.status(200).send(ReactDOM.renderToString(React.createElement(RoutingContext, renderProps))) 
    } else { 
     res.status(404).send('Not found') 
    } 
    }) 
}) 

server = http.createServer(app); 

server.listen('3000',() => { 
    console.log('Express server listening on port ' + PORT); 
}); 

私はNPMの実行を実行するときに、それは単にserver.jsnodeを呼び出して開始します。サーバーは正常に起動しますが、/testを含むすべての要求は404として戻ってきます。

私はconsole.logをreq.urlし、適切なURLを返しています。私は "ルート"ファイルについても同じことをしており、それは間違いなく正しいファイルを見つけることです。ここでは、これらのログからの出力は次のようになります。

Express server listening on port 3000 
URL: /test 
Routes: { default: 
    { '$$typeof': Symbol(react.element), 
    type: 
     { [Function] 
     displayName: 'Route', 
     createRouteFromReactElement: [Function: createRouteFromReactElement], 
     propTypes: [Object] }, 
    key: null, 
    ref: null, 
    props: { path: '/test', component: [Object] }, 
    _owner: null, 
    _store: {} } } 
Render Props: undefined 
GET /test 404 19.596 ms - 9 

renderPropsは常に定義されていないとの応答が404を返す私はきちんと例に従っ思ったが、私は私が間違っているところはわからないが。

+0

あなたは解決策を見つけましたか? – nrgwsth

答えて

1

私は私が 以下、この問題を修正可能性がいくつかのものは私の アプリケーションに変更を持っていたいくつかのポイントがある見つけ、長いデバッグした後、同様の問題を持っていた: -

i)は、すべてのテストコンポーネントの最初のコンポーネントをレンダリングするだけではなく、レンダリングできる適切なdom要素を返す必要があります。あなたは以下の例を参照してくださいneed.Please nullまたはなど多くの要素を含む適切なコンテナ要素のいずれかを返す必要があります。(これは私が自分のアプリケーションでやっていた最初の間違いだった。)

export default class Test extends React.Component { 

    constructor(props) { super(props); } 

    render() { 
       return (
        <div> 
         <h1>opopooopppopo</h1> 
         <p>This is your world.</p> 
        </div> 
       ); 
    } 
} 

II)RouterContextを使用しますあなたのコードベースでRoutingContextの代わりにこれは私のために働いた、これは私のコードで大きな問題でした。 RoutingContextでしたので、反応ルータの新バージョンではが推奨されていません。この変更により問題が解決されました。

res.status('200').send(ReactDOM.renderToString(<RouterContext {...renderProps}/>)); 

(注:反応-ルータモジュールからRouterContextをインポートすることを忘れないで下さい。)からルータコンテキストの

//インポート文を反応させ、ルータ

var RouterContext = Router.RouterContext; 

iii)上記のどれも動作しない場合は、routes.defaultの代わりにr外出変更:一致する{{routes:routes、location}}、この変更はbabel 6を使用している場合に必要です.RootingContextとRouterContextの組み合わせでこれを試してください。 -

a)res.status( '200')の組み合わせで(ルート:ルート))一致するようにしてください(ReactDOM 。renderToString(< RoutingContext {... renderProps} />));

B)一致({ルート:経路} res.statusの組み合わせ)( '200')(ReactDOM.renderToString(< RouterContext {...} renderPropsを送信/>));

C)マッチ({ルート:routes.default}。)res.statusの組み合わせ( '200')(ReactDOM.renderToStringを送る(< RoutingContext {...} renderProps />)) ;

D)一致({ルート:routes.default}。)res.statusの組み合わせ( '200')(ReactDOM.renderToStringを送る(< RouterContext {...} renderProps />)) ;

関連する問題