简体   繁体   中英

How to use react-router 2 as server side routing with expressjs?

使用react-router进行服务器端渲染本文档不足以理解如何使用react-router 2在服务器端渲染具有不同类型的http请求的react组件,例如get,post和put等。

Writing in details how to server side render react & react-router application could be very big topic.

I will assume that you are experienced user and you know how to use expressjs and how to create react & react-router app.

when you render server side you can create separate server routers to map each frontend route or create one which will take all urls.

Latter case need just one server router. Somewhere in the bottom of your server router (before errors routes) write:

app.use('/*', function(req, res){ ... });

this route will catch all urls.

First of all we need information about url. We don't need info about protocol or domain therefore we need only this:

var url = req.originalUrl;

Info about method (POST, GET, PUT, DELETE) we get from:

var method = req. method

If you want you can make separate routes and you would have:

app.post('/something', function(req, res) {...});
app.get('/something', function(req, res) {...});

It does not matter.

Second thing we don't use browser history for react-router! We have to use memory history.

Your history object:

var history = createMemoryHistory(req.originalUrl || '/');

And you pass history object to router.

I like to create my root component to accept as param history object. And when I use it in frontend I pass browser history, and when I use it in server render I pass memory history.

Below very simple example how server side rendering route could look (I used also ejs templates):

router.use('/*', function(req, res){
  var history = createMemoryHistory(req.originalUrl || '/');
  var initialState = {};
  //do something with initialState according to url and request method
  var staticHTML = ReactDOMServer.renderToString(
    React.createFactory(App)({
      history,
      initialState
    })
  );

  res.render('index', {
    staticHTML,
    initialState: JSON.stringify(initialState)
  });
});

In this example you need to populate initState based on user url and request method. And your app should on start use that init data.

Server side rendering also works like charm if you use redux. Because we have one store and one init state object. You can then pass during rendering any basic values. For example when you render list of objects then you take it in frontend and pass to init state and then render. Then rendered page will have values.

I'm working in react+react-router+redux+redux-react-router+expressjs example, it is not totally ready but works and you could see how I solved server rendering:

https://github.com/uhlryk/my-express-react-seed

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