1

When trying to render my react application on the server, I'm receiving the following error:

Error: Uncaught error: Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined.

Here is my server.js code, I've removed the server configuration for brevity.

import hapi from 'hapi';
import inert from 'inert';
import path from 'path';
import fs from 'fs';
import React from 'react';
import { ReactDOM, renderToString } from 'react-dom/server';
import { RouterContext, ReactRouter, match } from 'react-router';
import { Provider } from 'react-redux';
import routes from './src/config/routes';
import store from './src/flux/store';

...
      match({routes, location: request.url.path}, function(err, redirectLocation, renderProps) {

        if (err) {
          reply(err.message).status(500);
        } else if (redirectLocation) {
          reply()
            .redirect(redirectLocation.pathname + redirectLocation.search)
            .code(302);

        } else if (renderProps) {

          var element = (
            <RouterContext {...renderProps} />
          );

          console.log(element);

          reply(renderToString(element)).code(200);

        } else {
          reply('Page Not Found')
        }
     });

The renderProps block of the if statement is getting called, and this is where the error is thrown.

EDIT: When I console.log RouterContext after my import from react-router, I'm getting undefined.

You can view my package.json for versions here: http://pastebin.com/mpb6XSKu

1 Answer 1

1

The issue is that I was referring to the latest react-router docs for master which referred to "RouterContext." In version 1.0.2, this was named "RoutingContext." Changing my code to refer to the latter fixed one of the issues. This is my final working isomorphic server short of rendering static assets:

import hapi from 'hapi';
import inert from 'inert';
import React from 'react';
import { createStore } from 'redux';
import { ReactDOM, renderToString } from 'react-dom/server';
import { RoutingContext, ReactRouter, match } from 'react-router';
import { Provider } from 'react-redux';
import routes from './src/config/routes';
import initializeStore from './src/flux/store';

const server = new hapi.Server();

server.register(inert, err => {

  if (err) {
    throw err;
  }

  server.connection({
    host: '0.0.0.0',
    port: 80
  });

  server.route({
    method: 'GET',
    path: '/{path*}',
    handler: function (request, reply) {

      var url = request.url.path;

      var matcher = {
        routes,
        location: request.url.path
      };

      match(matcher, function(err, redirectLocation, renderProps) {

        if (err) {

          reply(err.message).status(500);

        } else if (redirectLocation) {

          reply()
            .redirect(redirectLocation.pathname + redirectLocation.search)
            .code(302);

        } else if (renderProps) {

          var element = (
            <Provider store={initializeStore()}>
              <RoutingContext {...renderProps} /> 
            </Provider>
          );

          reply(renderToString(element)).code(200);

        } else {
          reply('Page Not Found');
        }
     });
   }
  });

  server.start(function (err) {
    if (err) {
      throw err;
    }

    console.log('Server started');
  });
});
Sign up to request clarification or add additional context in comments.

Comments

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.