React offers an approach to render components to strings specifically for the case of server-side rendering.

That is accomplished by the react-dom package, that manages the React to Dom conversion.
However, we don’t need to simply render a view, however the correct view.

That’s where isomorphic or Universal routing comes into the picture.

Universality, sometimes called “isomorphism”, refers to ability to run nearly the same code on both client and server – a concept that was born out of the trials and tribulations in the past of creating applications on the web, availability of new technologies, and the ever-growing complexity of developing and maintaining these applications.

Why React server rendering?

A normal React application executes in the browser, rendering pages in the DOM in response to user actions. In order to improve the user experience, we want to render the pages server side and send the generated static content to the client side, this will ensure that our content is crawlable by search engines and also allow users with feature phones to consume our content.

Rendering a view

The fundamental concept is that we wrap the app in a stateless <StaticRouter> instead of a <BrowserRouter>. The primary difference between these two routers is that the location of the static router never changes, therefore helpful for our case, where we only have to compute the needed route and send the view back to the client.

let’s look at the client.js file.


// --- client.js

import React from 'react'
import { render } from 'react-dom'
import { BrowserRouter } from 'react-router-dom'

import App from './modules/App'

render((
 
 
 
), document.getElementById('app'));

In the code snippet above the client BrowserRouter stays the same and the server static router handles the incoming requests routing.

Now, let’s look at the server.js file.


// --- server.js

import path from 'path';
import React from 'react'
import express from 'express'
// we'll use this to render our app to an HTML string
import { renderToString } from 'react-dom/server'
// and these to match the url to routes and then render
import { StaticRouter } from 'react-router'
import App from './modules/App'

const app = express();

// serve our static stuff
app.use(express.static(path.join(__dirname, 'public')));

app.get('*', (req, res) => {
 const context = {}
 const markup = renderToString(
 
 )
 
 res.set('content-type', 'text/html');
 res.send(renderPage(html));
});

// We are using this function that renders an HTML
// with markup passed as parameter
function renderPage(appHtml) {
 return `
 
 
 Isomorphic Router Example
${appHtml}
` }

In the Code snippet above, we are mapping all requests through the app.get to React’s renderToString method from the react-dom package sent back to the client.
The talked about component markup shall be passed to a simple function that generates an HTML with the markup in it. And that is what Express will send back to the client.

 

 A Real-life case in React server rendering

Suppose a user wants to navigate to a protected URL or want to access some private information. In these cases, we use it like this:



// --- server.js

// ...

app.get('*', (req, res) => {
 const context = {}
 const markup = renderToString(
 
 )
 
 if (context.url) {
 // Somewhere a `` was rendered
 res.redirect(302, context.url);
 } else {
 res.set('content-type', 'text/html');
 // here you can use whatever view rendering technique that you like
 res.send(renderPage(html));
 }
 
});

// ...

In the Code Snippet Above, Whenever you render   on the client, the browser historychanges the state and we get a brand new screen.
In a static server environment, we are able to change the app state. Instead, we use the context prop to search out what the results of rendering was.
If we discover a context.url then we all know the app redirected. This permits us to send a correct redirect from the server. This redirect will make the router handle the following request as if nothing occurred.


Existing Eclipse User? Try CodeMix for productive React Development.


Conclusion

In this article we saw how to send the right view to the client, depending on the requested URL, even redirecting to the right URL if needed. the most common use case for server-side rendering is to handle the initial render when a user first requests our app. So,what about the initial state of the app? Yes, there is a lot more to cover in React server rendering, hopefully we will cover those in coming articles.

Advertisements