简体   繁体   中英

ReactDOMServer renderToStaticMarkup on Node/Express server

I'm trying to create a server rendered react app, the only part I'm stuck on is importing my components to my express server and getting the static markdown to send back to the user. Essentially what I have right now is this:

Express server:

const Report = require('../public/source/components/index.js').default;
....
router.get('/*', function(req, res, next) {
    var reportHTML = ReactDOMServer.renderToStaticMarkup(react.createElement(Report)))
    res.render('index', { title: 'Report' });
});

When I hit that route, I get the following error:

Warning: React.createElement: type is invalid -- expected a string
(for built-in components) or a class/function (for composite components)
but got: object. You likely forgot to export your component from the file
it's defined in. Check the render method of `ReportApp`.
in ReportApp

The contents of my index.js file, note that I stripped out a lot of the complexity involving graphql and setting the initial state, which is why this isn't a functional component.

import React, { Component } from 'react';
import Header from './header/Header';
import PageOneLayout from './pageOneLayout/PageOneLayout';
import styles from './main.scss';

const hexBackground = require('./assets/hex_background.png');

export default class ReportApp extends Component {
  render() {
    return (
      <div className={styles.contentArea}>
        <img src={`/build/${hexBackground}`} alt={'hexagonal background'} className={styles.hexBackground}/>
        <Header client={"client name"} />
        <div className={styles.horizontalLine}></div>
        <PageOneLayout chartData={this.state} />
      </div>
    )
  }
}

Any pointers in the right direction would be appreciated!

EDIT:

here's my webpack:

/* eslint-disable no-console */
/* eslint-disable import/no-extraneous-dependencies */
import autoprefixer from 'autoprefixer';
import nodemon from 'nodemon';
import ExtractTextPlugin from 'extract-text-webpack-plugin';

nodemon({
    script: './bin/www',
    ext: 'js json',
    ignore: ['public/'],
});

nodemon.on('start', () => {
    console.log('App has started');
}).on('quit', () => {
    console.log('App has quit');
}).on('restart', files => console.log('App restarted due to: ', files));

export default {
    watch: true,
    entry: './public/source/main.js',
    output: { path: `${__dirname}/public/build/`, filename: 'main.js' },
    module: {
        loaders: [
            {
                test: /\.jsx?$/,
                exclude: /node_modules/,
                loader: 'babel',
                query: {
                     presets: ['react', 'es2015', 'stage-1'],
                     plugins: ['transform-decorators-legacy'],
                     cacheDirectory: true
                 }
            },
            // {
            //     test: /\.jsx?$/,
            //     exclude: /node_modules/,
            //     loader: 'eslint',
            // },
            {
                test: /\.s?css$/,
                loader: ExtractTextPlugin.extract('style-loader', 'css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!postcss-loader!sass-loader?outputStyle=expanded&sourceMap')
            },
            { test: /\.jpe?g$|\.gif$|\.png$|\.svg$|\.woff$|\.ttf$|\.wav$|\.mp3$/, loader: "file", output: {path: `${__dirname}/public/build/`, filename: 'logo.svg'}},
        ],
    },
    // eslint: {
    //     configFile: './public/.eslintrc',
    // },
    resolve: {
        modulesDirectories: ['node_modules', 'public/source'],
        extensions: ['', '.js', '.jsx'],
    },
    postcss: [
        autoprefixer,
    ],
    plugins: [
        new ExtractTextPlugin('main.css', { allChunks: true }),
    ],
};

There are few things to consider:

  • Are you doing any code transpiling at server side?
  • How are you building your component bundle(show the config, I assume webpack)?
  • Make sure the bundle component exposes the component.
  • The extra createElement shouldn't be needed in this case ReactDOMServer.renderToStaticMarkup(react.createElement(Report))) .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM