Bases de reactjs

Tengo la suerte de haber comenzado a trabajar junto a los geniales @dandel y @d4vecarter en un proyecto en ReactJS que se presume de cierta envergadura. Y ahí estabamos nosotros, haciéndonos mil y una preguntas, tratando de tomar las mejores decisiones, cuando un compañero de la comunidad me escribió un mensaje privado por LinkedIn preguntándome cosas supuestamente básicas sobre ReactJS. Me llamó mucho la atención que muchas de sus preguntas no eran tan diferentes de nuestras propias dudas. Así que decidí recoger una parte de las cuestiones que nos hemos estado planteando y el camino que hemos tomado para resolverlas.

HTML en los ficheros JS. ¿De verdad?

Si estás leyendo esto, seguramente ya sabes del DOM Virtual, del algoritmo de Diff y, por supuesto, de JSX. Es lógico que cuando veas algo así:

var CommentList = React.createClass({  
  render: function() {
    return (
      <div className="commentList">
        Hello, world! I am a CommentList.
      </div>
    );
  }
});

lo primero que pienses es que estás metiendo HTML en tus ficheros JS. Pero eso NO es cierto. No hay que olvidar que JSX no es más que un azucarillo sintáctico para escribir esto:

var CommentList = React.createClass({  
  render: function() {
      return React.createElement('div', {className: commentList}, 'Hello, world! I am a CommentList.'),
  }
});

Si quieres escribir muchas clases anidadas, vas a preferir hacerlo con la sintaxis de JSX a hacerlo con JS plano. Así que no te agobies por escribir HTML en los ficheros JS, porque en realidad estás escribiendo JS en ficheros JS. :)

Puede no parecer evidente en un principio, pero al usar JSX no estás usando un lenguaje de plantillas con Jade o Handelbars. Solo estas simplificando la forma de escribir funciones en JS. Por eso, no trates de utilizar ningún sistema de plantillas en lugar de JSX; son cosas completamente distintas.

Organización

Una vez tienes claro que vas a empezar a desarrollar la app en ReactJS, hay que decidir cuáles son los componentes necesarios (y cuáles son prescindibles). El post de Diseño Atómico tiene algunas sugerencias muy útiles en este sentido. Se trata de partir el interfaz en sus partes más simples y comunes. Sobre estos pilares hay que ir montando elementos más complejos, hasta completar el desarrollo de la aplicación, que será la suma de todos los elementos que la componen.

El ejemplo perfecto de esto es atoms, el framework desarrollado por @soyjavi.

Propuesta organizativa del componente

Es fundamental crear un sustrato único sobre el que generar todos los componentes. De otra forma, esto se volvería un lío muy rápidamente. Así que una vez que hayas decidido qué componentes crear, usa esto o créate tu propio generador de componentes.

Aquí dejo una propuesta de cómo podría estar organizado un componente:

├── doc
├── package.json
└── src
    ├── component-variant
    │   ├── index.jsx
    │   └── index.scss
    ├── index.jsx
    └── index.scss

En el ejemplo, se expone un único punto de entrada al componente, además de un único css para las reglas básicas.

En cuando a las las reglas css que habría que aplicar a un componente, sería deseable que solo sean aquellas que estén relacionadas con su layout y no con el diseño. Lo óptimo es proporcionar un diseño lo más neutro posible y dejar la customización al usuario final.

Iso... ¡¿Qué?!

Isomórfico. El siguiente paso que vas a querer dar es conseguir que tu aplicación sea isomórfica. Esto quiere decir que se puede ejecutar la aplicación directamente en el servidor y enviarla a los clientes, si estos no disponen de Javascript. En otras palabras, el isomorfismo nos permite obtener la cadena HTML que en última instancia representa a nuestro componente sin que este llegue a ejecutarse en el browser. Esto no es otra cosa que el Santo Grial en las single-page applications (SPAs), ya que indexa contenido que solo estaría disponible en browsers con Javascript activado, cosa que no ocurre, por ejemplo, con el bot de Google.

Si tuvieramos un componente simple como el sigue:

var CommentBox = React.createClass({  
  render: function() {
    return (
      <div className="commentBox">
        Hello, world! I am a CommentBox.
      </div>
    );
  }
});

y quisiéramos renderizar el div.commentBox en un capa con id content, entonces haríamos una llamada en alguna parte de nuestro programa parecida a lo que sigue:

React.render(  
  <CommentBox />,
  document.getElementById('content')
);

Aquí la clave es que estamos llamando al método render de ReactJS. Esto convierte nuestro código JSX a un DIV en nuestro DOM en la página web. Pero tenemos otra opción, que es llamar al método renderToString y pasarle nuestro componente:

let html = React.renderToString( <CommentBox/> );

// html contiene el string que representa al componente.

Esta opción es interesante, porque nada nos impide llamar a React.renderToString desde nuestro servidor, pasarle la salida a una variable de un template y crear una página web entera en el servidor, que contará con el HTML estándar y con el HTML que ha generado nuestro componente de ReactJS.

El isomorfismo es un tema muy complejo, con muchos detalles a controlar para que la aplicación funcione correctamente. Por ejemplo, hay ciertos eventos en el ciclo de vida de un componente que no se lanzan cuando llamamos a renderToString. Lo mejor que puedes hacer es leerte el código fuente de los frameworks que se supone que ya están preparados para hacer aplicaciones isomórficas con ReactJS. Para acabar, te recomiendo este artículo y este libro si quieres profundizar más sobre el isomorfismo.

Si te ha gustado este post, difunde la palabra. Tampoco dudes en dejar comentarios u observaciones. ¡Gracias! :)

Suscríbete a mi lista de correo

* Campos obligatorios