Reputation: 7719
I'm trying to make react router v1.0 working, but when I'm writing a router for Server Side Rendering, I get this error in browser : React is undefined
router.js
:
'use strict';
import { Router, Route, match, RoutingContext } from 'react-router';
import routes from './routes';
import {renderToString} from 'react-dom/server';
export default function(req, res, next) {
match({routes, location: req.url}, (error, redirectLocation, renderProps) => {
if (error) {
res.status(500).send(error.message)
} else if (redirectLocation) {
res.redirect(302, redirectLocation.pathname + redirectLocation.search)
} else if (renderProps) {
let markup = renderToString(<RoutingContext {...renderProps} />);
res.render('index', {markup: markup});
} else {
res.status(404).send('Not found')
}
})
};
I this file in express server.js
import express from 'express';
import path from 'path';
import favicon from 'serve-favicon';
import logger from 'morgan';
import cookieParser from 'cookie-parser';
import bodyParser from 'body-parser';
import exphbs from 'express-handlebars';
import router from '../shared/routes/router';
import routes from "../shared/routes/routes";
const app = express();
// view engine setup
app.engine('handlebars', exphbs({defaultLayout: 'main', extname: '.handlebars'}));
app.set('views', './views'); // ????
app.set('view engine', 'handlebars');
// uncomment after placing your favicon in /public
app.use(favicon('favicon.ico'));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
//app.use(require('less-middleware')(path.join(__dirname, 'dist')));
app.use(express.static('./public'));
app.use(router);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
//.... the rest of code
I'm doing pretty the same as here. When I look at the transpiled code (using babelify) I see :
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = function (req, res, next) {
(0, _reactRouter.match)({ routes: _routes2.default, location: req.url }, function (error, redirectLocation, 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((0, _server.renderToString)(React.createElement(_reactRouter.RoutingContext, renderProps)));
} else {
res.status(404).send('Not found');
}
});
};
var _reactRouter = require('react-router');
var _routes = require('./routes');
var _routes2 = _interopRequireDefault(_routes);
var _server = require('react-dom/server');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
;
But doesn't browserify, babelify and react router suppose to take care of this by bringing required modules in to the code ?
Upvotes: 0
Views: 1030
Reputation: 67296
You can see from your transpiled output that jsx is converted to:
React.createElement(_reactRouter.RoutingContext, renderProps)
This needs a reference to React
in order to run.
Simply adding an import to the top of router.js
should take care of the issue:
'use strict';
import { Router, Route, match, RoutingContext } from 'react-router';
import routes from './routes';
import {renderToString} from 'react-dom/server';
import React from 'react';
Browserify only understands how to read in the modules that you import. So, in this case, you must explicitly import React
.
Upvotes: 2