Cómo usar ReactJS en un proyecto Meteor


En el mundo del desarrollo frontend existen 3 librerías que sobresalen sobre las demás en cuanto a popularidad: React, Angular y Vue.js.

React en el 2016 ha tenido una gran tracción por el éxito del proyecto React Native, el cual permite crear aplicaciones móviles con Interfaces nativas para tanto iOS como Android usando Javascript.

También es legendario el rendimiento de las aplicaciones Web creadas con React, gracias a su virtual DOM.

Para utilizar React con Meteor sólo tienes que instalarlo a través de npm luego de crear el proyecto:

meteor create react-app && cd react-app
meteor add kadira:flow-router
meteor npm i react react-dom react-mounter --save

Muchos de los que empiezan con Meteor me preguntan cuál es el punto de entrada a la aplicación. Es el Router, respondo. Aquí puedes usar tanto React Router como Flow Router, utilizaré este último.

Creando la primera ruta

Elimina todos los ficheros dentro de la carpeta client y crea el fichero routes.js:

import React from 'react'
import {mount} from 'react-mounter'

FlowRouter.route('/', {
  name: 'home',
  action( params ) {
    console.log('Estamos en HOME');
  }
});

Observa que el segundo parámetro pasado a FlowRouter.route() es un objeto, el cual tiene una propiedad action cuyo valor es una función. Esta función recibe los parámetros de la ruta actual.

En esta función se renderiza el componente asociado a la ruta, en este caso, el componente Home. Dicho componente no existe, por lo que debemos crearlo:

// client/components/home.js

import React from 'react'

class Home extends React.Component {
  render() {
    return (
      <div className="jumbotron">
        Componente Home
      </div>
    )
  }
}

export default Home;

Si eres nuevo en React, debes conocer que toda tu UI son componentes, los cuales se componen unos con otros para crear el resultado final. Observa que en React las clases a los elementos html se especifican con className.

Toda aplicación web tiene elementos comunes para todas las páginas, como el header y el footer. En el ejemplo actual el componente Home sería la “página”, la cual se renderiza dentro del Layout que alberga las zonas comunes.

El Layout no existe aún, créalo y añádele el siguiente contenido:

// client/comun/layout.js

import React from 'react'
export default class extends React.Component {
  render() {
    return (
      <div className="layout">
        <h1> Header común </h1>
        
        { this.props.contenido() }
        
        <footer>
          MyCyberAcademy.com - Aprende sin límites
        </footer>
      </div>
    );
  }
}

Cada componente en React tiene propiedades que se les pueden definir a la hora de renderizarlo. En este caso, el Layout tiene una propiedad llamada contenido cuyo valor es una función.

Si el Layout tuviese una propiedad saludar que no fuese una función, se accedería a ella así: this.props.saludar.

Renderizando el componente Home

En la definición de la ruta, se utiliza la función importada mount para renderizar el componente. Primero lo importamos junto con el Layout.

// client/routes.js

import React from 'react'
import {mount} from 'react-mounter'

import Layout from './comun/layout.js'
import Home   from './components/home.js'

FlowRouter.route('/', {
  name: 'home',
  action( params ) {
    console.log('Estamos en HOME');

    mount( Layout, {
      contenido: function() { return (<Home />) },
      saludar  : "Hola, esta propiedad está disponible en Layout"
    });
    
  }
});

Observa cómo en el primer parámetro se especifica el componente Layout y en el segundo las propiedades que tendrá. En este caso, la función contenido y el string saludar . Ahora lee nuevamente el contenido del Layout para que veas cómo se invocan tales propiedades.

Prueba que funciona

El proyecto no lo hemos ejecutado aún, hazlo con el comando meteor. Accede a http://localhost:3000 en tu navegador y observa en la consola el mensaje “Estamos en Home” y en pantalla el componente Home renderizado junto al Layout.

Crea otra ruta

Para crear más rutas debes duplicar el código anterior, cambiar el nombre de la ruta, la dirección y montar otro componente distinto de Home.

En el siguiente snippet te muestro cómo hacerlo, observa que esto es equivalente al código anterior, solo que en este caso hago uso de ES2015 (también llamado ES6) para montar el componente .

// client/routes.js

import React from 'react'
import {mount} from 'react-mounter'

import Layout   from './comun/layout.js'
import Contacto from './components/contacto.js'

FlowRouter.route('/contacto', {
  name: 'contactar',
  action( params ) {
    
    mount( Layout, {
      contenido: () => <Home hola="Accede como this.props.hola"/>,
      saludar  : "Hola, esta propiedad está disponible en Layout"
    });
    
  }
});

Usando parámetros de Ruta

Caso de uso: mostrar los datos asociados a un producto. El producto es accedido mediante su Id.

Para lograr lo anterior necesitas pasarle el Id del producto al componente a renderizar, para ello solo tienes que usar el operador spread de ES2015:

FlowRouter.route('/ver/producto/:id', {
  name: 'listar_producto',
  action( params ) {
    
    mount( Layout, {
      contenido: () => <Producto {...params} />,
      saludar  : "Hola, esta propiedad está disponible en Layout"
    });
    
  }
});

Listo, con lo anterior puedes renderizar todos los componentes de tu app y pasarle datos. El operador spread es útil porque si tu ruta tiene muchos parámetros, por ejemplo: /ver/:categoria/producto/:id, tanto la variable categoria como el id estarán disponibles en el componente como this.props.categoria y this.props.id.

Recuerda que para que la ruta anterior funcione debes importar el componente <Producto /> en el fichero routes.js y puedes definirlo de la siguiente manera:

// client/components/producto.js

import React from 'react'

export default class extends React.Component {
  render() {
    return (
      <div className="container">
        <p>
          Este es el componente Producto,
          que pertenece a la categoría:
          { this.props.categoria }, el cual
          tiene el ID { this.props.id }
        </p>
      </div>
    );
  }
}

Te recomiendo, cuando vayas a mostrar props en la vista, uses el operador de asignacion desestructurada de JavaScript 2015 (el ya mencionado ES2015 o ES6):

// client/components/producto.js

...
render() {
    /* asignación desetructurada */
    const { categoria, id } = this.props;

    return (
      <div className="container">
        <p>
          Este es el componente Producto,
          que pertenece a la categoría:
          { categoria }, el cual
          tiene el ID { id }
        </p>
      </div>
   );
}
...

Conclusiones

El código de este tutorial lo puedes encontrar en Github.

Si eres nuevo en Meteor o no sabes lo que es, puedes ver los tutoriales sobre guía de inicio aquí en MyCyberAcademy. ReactJS, aunque al principio es un poco extraño para el que está acostumbrado a usar un motor de plantillas como Twig, Blaze o HTML plano, es uno de los frameworks más populares para el desarrollo frontend actual.

En próximos artículos trataré temas sobre cómo obtener datos del servidor usando React. Cualquier duda plásmala en los comentarios. Si te gustó el artículo compártelo con tus colegas, a ellos también les puede encantar.

Hasta pronto.