Search code examples
javascriptreactjstypescriptreact-routerserver-rendering

ReactRouter.match has no callback arguments when attempting to server-render react elements


I've tried following this guide and this question, but am getting undefined for all callback arguments when ReactRouter.match is fired.

This is my server:

var app = new (require('express'))()
var port = 3000

var ReactDomServer = require('react-dom/server');
var ReactRouter = require('react-router');
var routes = require('./es6/routes.js');

app.use(function(req, res) {
    console.log(req.url);
    ReactRouter.match({ routes: routes, location: req.url }, function(error, redirectLocation, renderProps) {
        console.log('error', error); // undefined
        console.log('erredirectLocationror', redirectLocation); // undefined
        console.log('renderProps', renderProps); // undefined
    });
})

app.listen(port, function(error) {
  if (error) {
    console.error(error)
  } else {
    console.info("==> Listening on port %s. Open up http://localhost:%s/ in your browser.", port, port)
  }
})

like the comments show, error, redirectLocation, and renderProps all log as undefined.

Logging the routes variable kicks off:

{ default: 
   { '$$typeof': Symbol(react.element),
     type: 
      { [Function]
        displayName: 'Route',
        createRouteFromReactElement: [Function: createRouteFromReactElement],
        propTypes: [Object] },
     key: null,
     ref: null,
     props: { path: '/', component: [Function: App], children: [Object] },
     _owner: null,
     _store: {} } }

It starts as a typescript file, routes.tsx:

import * as React from 'react'
import { Route } from 'react-router'
import App from './containers/app';
import Home from './containers/home';

export default (
    <Route path='/' component={App}>
        <Route path='/home' component={Home} />
    </Route>
)

which compiles to es6/routes.js

"use strict";
const React = require('react');
const react_router_1 = require('react-router');
const app_1 = require('./containers/app');
const home_1 = require('./containers/home');
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = (React.createElement(react_router_1.Route, {path: '/', component: app_1.default}, React.createElement(react_router_1.Route, {path: '/home', component: home_1.default})));
//# sourceMappingURL=routes.js.map

What am I missing?


Solution

  • You are getting undefined values because nothing is matching, it's 404ing.

    The reason that nothing is matching is because you are mixing es5 and es6 modules. Try passing routes.default into match().