reactjs - 将服务器端渲染添加到 create-react-app

标签 reactjs redux react-router create-react-app server-rendering

我正在研究 create-react-app 和 SSR。

我在此存储库中添加了 redux 和 React-router => https://github.com/sarovin/StarteKit .

现在我想添加 SSR(服务器端渲染)而不对 create-react-app 进行任何修改。

我有一个 PR,我尝试实现它 => https://github.com/sarovin/StarteKit/pull/1

但是我有一些错误,因为函数 onClick() 在我的示例中不起作用:

//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"));
});

有什么建议吗?

最佳答案

如果你需要服务器端渲染,我建议使用 Next.js 而不是 create-react-app: https://github.com/zeit/next.js/

关于reactjs - 将服务器端渲染添加到 create-react-app,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40179203/

相关文章:

ios - 将 react-native-router-flux 与 redux 一起使用,如何更新 View 组件中的状态?

javascript - 如何通过 react-redux 的 useSelector 钩子(Hook)正确使用柯里化(Currying)的选择器函数?

javascript - react-router 1.0 路由被express.js服务器拾取

javascript - 从 react router v4 中的 redux 操作重定向

reactjs - react-grid-layout - 失败的 Prop 类型 : Layout property must be an object. 已收到:[对象数组]

reactjs - 在 React/Nextjs 中导入文件夹中的多个文件

javascript - useEffect 在自定义钩子(Hook)中使用 ref 缺少依赖项警告

javascript - 使用 browserify 响应 js

javascript - redux-saga 中的 getState?

reactjs - 如何在页面导航上保留状态数据?