Arian
Arian

Reputation: 7719

React is Undefined when using ReactDOM

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

Answers (1)

Davin Tryon
Davin Tryon

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

Related Questions