MartaJ MartaJ - 4 months ago 154
Node.js Question

"Invariant Violation" Using React Server renderToString on Server-Side

I'm trying to set up an isomorphic server-side rendering React app using Webpack, but am getting this error when I try turning my React code into a string using renderToString:

Warning: React.createElement: type should not be null, undefined, boolean, or number. It should be a string (for DOM elements) or a ReactClass (for composite components).
Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.

I stop getting this error when I comment out the line with the renderToString function (of course, the app still doesn't work - I just no longer get an error message).

I've tried passing renderToString
<RootApp />
instead of making a factory, and neither of those has worked. Using
resulted in the same error, and using
<RootApp />
threw an
unexpected token < error

And ideas on what could be going on?

My app looks like:


"use strict"

const Express = require('express');
const BodyParser = require('body-parser');
const Path = require('path');
const Fs = require('fs');
const Url = require('url');
const ReactRouter = require('react-router');
const React = require('react');
const ReactDOMServer = require('react-dom/server');

const app = Express();
app.set('view engine', 'ejs');

app.get('*', (req, res) => {
let RootApp = require('./components/app.jsx');
let rootAppFactory = React.createFactory(RootApp);
let reactHtml = ReactDOMServer.renderToString(rootAppFactory({}));
res.render('index', {reactOutput: reactHtml});

if (process.env.NODE_ENV !== 'test') {
let port = process.env.port || 4000;
console.log('Listening on port', port);
} else {
module.exports = app;


import React, {Component} from 'react';
import ReactDOM from 'react-dom';

class App extends Component {

render() {
return (


export default App;


<!DOCTYPE html>

<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="">



<div id="root">
<%- reactOutput %>
<script src="bundle.js"></script>



Ended up getting this working. The issue was in how I was requiring app.jsx in app.js - because I'm using require instead of import, I needed to change require('./components/app.jsx') to require('./components/app.jsx').default to get the default export.