2

i am studying create-react-app and SSR.

I have add redux and react-router in this repo => https://github.com/sarovin/StarteKit.

Now i want add SSR ( server side rendering ) without any modification to create-react-app.

I have a PR where i try to implement it => https://github.com/sarovin/StarteKit/pull/1

But i have some error because the function onClick() not work in my example:

// App.js

import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux';
import { switcher } from './actions/switcher';
import logo from './logo.svg';
import './App.css';

const propTypes = {
  switch: PropTypes.bool,
  dispatch: PropTypes.func,
};

class App extends Component {
  constructor(props) {
    super(props);
    this.onClick = this.onClick.bind(this);
  }

  onClick() {
    console.log('onClick');
    this.props.dispatch(switcher());
  }

  render() {
    console.log('Switch', this.props.switch);
    return (
      <div className="App">
        <div className="App-header">
          {this.props.switch ? <img src={logo} className="App-logo" alt="logo" /> : null }
          <h2>Welcome to React</h2>
        </div>
        <label className="switch" >
          <input checked={this.props.switch} type="checkbox" onChange={this.onClick} />
          <div className="slider round"></div>
        </label>
      </div>
    );
  }
}

function mapStateToProps(state) {
  return {
    switch: state.switcher.get('switch'),
  };
}

App.propTypes = propTypes;

export default connect(mapStateToProps)(App);

//server.js

import express from 'express';
import path from 'path';
import bodyParser from 'body-parser';
import hbs from 'express-hbs';
import cors from 'cors';
import React from 'react';
import { createStore, combineReducers } from 'redux';
import { Provider } from 'react-redux';
import { renderToStaticMarkup } from 'react-dom/server';
import { RouterContext, match } from 'react-router';
import routes from './routes';
import * as reducers from './reducers';

console.log('info', 'Init App');

const app = express();
app.set("port", process.env.PORT || 8080);
app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
// Make index false, so that it is not resolved by default.
app.use(express.static(path.resolve('build'), {index: false}));

app.set("views", path.resolve('build'));
app.set("view engine", "html");
app.engine("html", hbs.express4());

app.use((req, res, next) => {
  match({routes: routes, location: req.url}, (err, redirectLocation, renderProps) => {
    if (err) {
      return res.status(500).send(err.message);
    } else if (redirectLocation) {
      res.redirect(302, redirectLocation.pathname + redirectLocation.search);
    } else if(renderProps){
      res.status(200);

      console.log(renderProps);

      const reducer = combineReducers(reducers);
      const initialState = {};
      let store = createStore(reducer, initialState);

      let html = renderToStaticMarkup(
        <Provider store={store}>
          <RouterContext {...renderProps}/>
        </Provider>
      );

      console.log('store', store.getState());
      res.render('index.html', { content: html });
    }
    else res.status(404).send('Page not found');
  });
});

app.listen(app.get("port"), () => {
  console.log("Express server starting on port: " + app.get("port"));
});

Have any suggestion?

4
  • 1
    FYI, Create React App explicitly does not support servw rendering. It says so on its homepage. Commented Oct 22, 2016 at 12:22
  • It looks like you made it work (the PR has been merged). Didn't you ? Commented Dec 28, 2016 at 17:55
  • @vcarel The PR has been merged in my repo Commented Dec 29, 2016 at 8:46
  • stackoverflow.com/a/48851269/82686 Create React App + Server-side rendering (SSR) Commented Feb 20, 2018 at 23:38

4 Answers 4

2

If you need server side rendering, I would suggest Next.js instead of create-react-app: https://github.com/zeit/next.js/

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

Comments

0

I'll strongly recommend razzle for your project. it abstracts all the required tooling for your universal JavaScript application into a single dependency which is a great gain doing SSR.

Comments

0

I've been thinking about the same thing. I ended up with a project https://github.com/haukurk/cra-ssr-ts-recipe. It's an isomorphic web app that allows you to do server rendering for React (with support for React Router and Redux). You simply add fetchData function to your route component if you want to do any pre-fetching of data.

SSR is not something that is trivial nor built into React/CRA and will always include some extra work for your web app.

I've also been looking into NextJS, as people seem to be praising it a lot. I encourage you to look at that.

Comments

0

Please try

https://github.com/antonybudianto/cra-universal

No need to eject and it's zero config by default (v3.0.x)

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.