Renderizando componentes de ReactJS desde el servidor

Si quieres empezar aprendiendo a crear tu primer componente, haz click aquí.

ReactJS es una librería creada por Facebook con el fin de crear interfaces de usuario y animar el desarrollo de las Single Page Applications (aplicaciones de una sola página). Esta librería está constantemente mantenida por el equipo de Facebook e Instagram (empresa comprada por Facebook) y por los desarrolladores de su comunidad en GitHub.

Durante este último mes estuve desarrollado una app en ReactJS que se encuentra en beta privada. Al enseñársela a varios desarrolladores me comentaron la posibilidad de renderizar ReactJS desde Node en vez de usar Jade ya que es bastante lento y entorpece la carga de la aplicación. Esto derivó en una larga discusión con Sergio Xalambrí en Platzi que me ayudó un poco a orientarme sobre este proceso.

Durante este tutorial realizaremos, paso a paso, los procesos necesarios para empezar a hacer render de nuestros componentes desde React y Node, partiremos de una base la cual son los componentes del sitio, es decir los del FrontEnd. Estos son los que forman un build.js, el cual va al HTML o a un Jade. En este caso solo tenemos uno que es la barra de arriba de este sitio, como veremos al final del ejemplo.

Si deseas ver el código del ejemplo tienes el repositorio en Github. Si miras los commits es prácticamente el proceso paso a paso.


Paso 1: Instalar las dependencias

Instalaremos solo las dependencias necesarias para los pasos aquí mostrados, las descargaremos usando NPM

$ npm install --save express react react-dom

Paso 2: Creando un componente que será redenderizado en el servidor

Crearemos un componente en src/server y lo llamaremos app.jsx.

Este básicamente contendrá una plantilla HTML (yo he usado la que da el plugin Emmet). Esto es lo que renderizará Node. Este componente tiene un enlace al build.js, de esta manera podemos hacer render de los componentes del Front. El motivo de esto es que el método que vamos a usar desde Node no nos permite usar cosas como componentWillMount().

import React from 'react'
class MyAwesomeApp extends React.Component {  
render() {
return(
<html lang="en">
<head>
<meta charSet="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta httpEquiv="X-UA-Compatible" content="ie=edge" />
<link rel="stylesheet" href="https://miguhruiz.xyz/public/css/index.css" />
<title>My awesome app rendered at the server</title>
</head>
<body>
// El lugar donde el build colocará los componentes.
<div className="react-app"></div>
// El archivo con la lógica de nuestros componentes, en este caso el header.
<script src="./public/js/app.js"></script>
</body>
</html>
)
}
}
export default MyAwesomeApp

Paso 3: Renderizando el componente MyAwesomeApp desde NodeJS

Para esto usaremos el módulo react-dom aunque invocaremos a react-dom/server y solo usaremos su método renderToString.

Seguidamente traemos el componente y lo convertimos a un HTML compilado con el método mencionado anteriormente. Para acabar se lo pasamos a la ruta / cuando sea solicitada.

Partimos de un servidor de Express básico, si quieres aprender como hacerlo, lee este increíble artículo.

import React from 'react'  
import { renderToString } from 'react-dom/server'
// Traemos el componente
import Component from './src/server/app.jsx'
// Lo pasamos a string
const App = renderToString(<Component />)
// Lo enviamos al entrar en la ruta, es decir el HTML compilado
app.get('/', (req, res) => {
res.send(App)
})

Al iniciar el servidor de Express y solicitar el sitio nos encontraremos con el resultado:

Si tienes alguna duda o te gustaría comentar algo escribe tu comentario más abajo. Estoy para ayudarte.