Alex Alex - 1 month ago 15
Node.js Question

React router server side unexpected behaviour

I the following server.js:

import express from 'express';
import path from 'path';
import React from 'react';
import { renderToString } from 'react-dom/server';
import { match, RouterContext } from 'react-router';
import routes from './src/client/app/config/routes.jsx';

let port = process.env.PORT || 8080;
let app = express();

app.use(express.static('src/client/'));

// app.get('/', (req, res) => {
// res.sendFile(path.resolve(__dirname + '/src/client/index.html'))
// });

app.get('*', (req, res) => {
match(
{ routes, location: req.url },
(err, redirectLocation, renderProps) => {

// in case of error display the error message
if (err) {
return res.status(500).send(err.message);
}

// in case of redirect propagate the redirect to the browser
if (redirectLocation) {
return res.redirect(302, redirectLocation.pathname + redirectLocation.search);
}

// generate the React markup for the current route
let markup;
if (renderProps) {
// if the current route matched we have renderProps
markup = renderToString(<RouterContext {...renderProps}/>);
}
// else {
// // otherwise we can render a 404 page
// markup = renderToString(<NotFoundPage/>);
// res.status(404);
// }

// render the index template with the embedded React markup
return app.use(express.static(path.join(__dirname + '/src/client/index.html')));
}
);
});

app.listen(port);
console.log('server started');


routes.jsx

import React from 'react';
import { Route, Router, browserHistory } from 'react-router';
import ReactDOM from 'react-dom';

import Wrapper from './../components/wrapper.jsx';
import Home from './../components/home.jsx';
import Projects from './../components/projects.jsx';
import SingleProject from './../components/projectContent/singleProject.jsx';
import About from './../components/aboutUs.jsx'

if(typeof window !== 'undefined') {
console.log('here baby');
ReactDOM.render((
<Router history={browserHistory} >
<Route component={Wrapper} >
<Route path="/" component={Home} />
<Route path="projects" component={Projects} />
<Route path="projects/:id" component={SingleProject} />
<Route path="about" component={About} />
</Route>
</Router>
), document.getElementById('app'));


I can access my app at localhost:8080/ however when I refresh the browser manually it goes into an infinite loop without refreshing the page completely. Since the server side implementation I was expecting that refreshing the browser would work as normal.

If I change

app.get('*', (req, res) => {


to

app.get('/', (req, res) => {


when I refresh the page I get "CANNOT get ..."

Answer

You're returning app.use() inside of app.get() which is what is probably causing your infinite loop. You should be rendering the markup being generated by renderToString() instead:

...
// render the index template with the embedded React markup
return res.render('index', { markup: markup });