Tutorials Directory
React+redux Tutorials (i) Connect, Applymiddleware, thunk, Webpackhotmiddleware
React+redux Tutorial (ii) Redux's single State tree completely replaces the react state machine?
React+redux Tutorial (iii) reduce (), filter (), map (), some (), every () 、... Expand Properties
React+redux Tutorial (iv) Undo, Devtools, router
React+redux Tutorial (v) asynchronous, single State tree structure, componentwillreceiveprops
React+redux Tutorial (vi) Redux service-Side rendering process
The serial ...
Today, we are going to explain the React+redux server rendering. Personally, react defeated Angular's true "killer" is the service-side rendering. Why we want to achieve service-side rendering, mainly for the SEO.
Example
Examples are still official counter examples, but we have implemented server-side rendering and state preloading.
Source:
Https://github.com/lewis617/myReact/tree/master/redux-examples/universal
Virtual API
First, we want to emulate an API that is used to request data asynchronously. The code is as follows:
Common/api/counter.js
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min)) + min
}
export function fetchCounter(callback) {
// Rather than immediately returning, we delay our code with a timeout to simulate asynchronous behavior
setTimeout(() => {
callback(getRandomInt(1, 100))
}, 500)
// In the case of a real world API call, you‘ll normally run into a Promise like this:
// API.getUser().then(user => callback(user))
}
Server-side Request API, sending HTML strings and state
Server/server.js (partial code)
// This is fired every time the server side receives a request
app.use(handleRender)
function handleRender(req, res) {
// Query our mock API asynchronously
fetchCounter(apiResult => {
// Read the counter from the request, if provided
const params = qs.parse(req.query)
const counter = parseInt(params.counter, 10) || apiResult || 0
// Compile an initial state
const initialState = { counter }
// Create a new Redux store instance
const store = configureStore(initialState)
// Render the component to a string
const html = renderToString(
<Provider store={store}>
<App />
</Provider>
)
// Grab the initial state from our Redux store
const finalState = store.getState()
// Send the rendered page back to the client
res.send(renderFullPage(html, finalState))
})
}
function renderFullPage(html, initialState) {
return `
<!doctype html>
<html>
<head>
<title>Redux Universal Example</title>
</head>
<body>
<div id="app">${html}</div>
<script>
window.__INITIAL_STATE__ = ${JSON.stringify(initialState)}
</script>
<script src="/static/bundle.js"></script>
</body>
</html>
`
}
- API is written, we call this API, Fetchcounter, this API function will also produce a callback, we get the counter value in the callback
- If there are parameters in the middleware request, the const params = Qs.parse (req.query), counter is parseint (Params.counter, 10). Otherwise counter returns the value Apiresult for the callback in the API, or 0 if none of the first two. QS is used to parse the HTTP querystring in the request, is it? Param=sth.
- Get counter, we get the state, with state as a parameter, regenerate a store instance, each time to regenerate a new store instance. Then generate an HTML string with react's service-side rendering, send it out
- At the same time, we also send a const FINALSTATE = store.getstate () out, let the client get this state rendering, why? Because you want to ensure that the client and server render the same components.
The service-side rendering of "The trousers Don't make a parade"
Since there is service-side rendering, why also use client-side rendering, because the server rendering is "lift pants do not recognize", rendering finished, our program will not move (because it is a bunch of strings), the client can let the program continue to move, because the client has JS, you can invoke the method to redraw the browser interface.
The client gets the state and renders it again.
Now that you want to render again, why is the server rendering? In order to SEO, our service-side rendering is not just for users to see, mainly for those "low-energy" web crawler to see.
Well, endure the fire, we continue to work, the client renders again.
const initialState = window.__INITIAL_STATE__
const store = configureStore(initialState)
const rootElement = document.getElementById(‘app‘)
render( <Provider store={store}>
<App/>
</Provider>, rootElement
)
In fact, client-side rendering also gets an initial state, then render it, without a lot of code.
Our state is obtained from window.__initial_state__ because the server has placed the state of the client on the global variable.
Preload state for "iffy"
Preload state, said so "iffy", as if very tall, in fact, is the state in the server over the generation of good, and then passed directly to the client. Not so "iffy."
React+redux Tutorial (vi) Redux service-Side rendering process