0

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 ?

2
  • Have you tried to import React in your react.js? Commented Nov 24, 2015 at 18:37
  • You mean router.js ? Commented Nov 24, 2015 at 18:42

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

4 Comments

That's right. My question is why do we have to import something which is not directly used ? Is it because of bad design ?
It is directly used after Babel transpiles the JSX.
I know , but I mean you cannot see it being directly used from the original code (before transpiling). anyways, it works now. thanks
@ArianHosseinzadeh the only way it's try to use it ) i've got the same problem :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.