React, primera entrega.

Cada vez que se propone en un proyecto crear una aplicación web y alguien sugiere utilizar una determinada tecnología de plantillas (templates) básicamente están comprometiendo gran parte de su esfuerzo a tratar de utilizar una tecnología que fue diseñada para crear documentos científico-técnicos (HTML) y adaptarla a aplicaciones, objetivo muy distinta para lo que fue creada.

Todo sistema de plantillas tiene 2 funciones principales:

  1. Fragmentar y componentizar recursos de la interfaz de usuario, evitando así duplicar código.
  2. Mostrar contenido dinámico.

La segunda función requiere al menos de básicos elementos de lógica (if/else, loops, etc.) para ser viable su uso por lo que muchos sistemas de plantillas incluyen algunas variaciones de estos permitiendoles ser en mayor o menor medida lenguajes totalmente Turing Completos.

Típicamente los sistemas de plantillas se basan en el paradigma Modelo-Vista-Controlador, intentando convertirse en la parte de la Vista. En todos la separación de intereses se fuerza artificialmente para lograr un objetivo. Hasta ahora ha funcionado relativamente bien. Con la creciente complejidad de las aplicaciones web y la explosión de Single Page Apps (SPA) o Aplicaciones de una Sola Página los sistemas de plantillas han venido tratando de mantener su utilidad, cada vez con menos éxito.

Enter the React World

ReactJS, es una librería OpenSource escrita en JavaScript desarrollada en Facebook e Instagram que pretende simplificar el desarrollo de aplicaciones Web de una sola página donde los datos cambian en el tiempo.

Del sitio web de React podemos sacar estas propiedades:

  • Simple: Solo debemos expresar como debe lucir nuestra aplicación en cualquier momento de acuerdo a los datos subyacentes.
  • Declarativo: Cuando los datos cambian, React conceptualmente es como si oprimiera un boton de refrescar que modifica las partes que cambian, gracias a una implementacion de DOM virtual es realmente rápido.
  • Componentes Componibles: Todo en React son componentes, siendo más sencillo encapsular, reusar, probar y consecuentemente permitir mejor separación de intereses.
Que no es React?

React no es:

  • NO es un MVC Framework. React ES una librería para construir componentes de interfaces reusables y componibles que se actualizan a medida que sus datos subyacentes cambian en el tiempo.
  • React NO utiliza plantillas. React utiliza una abstracción orientada a componentes, lo que implica que para crear las vistas de estos se utiliza directamente Javascript que es un lenguaje mucho más potente que simples variaciones de if/else, loops, etc.
Veamos un ejemplo

Hagamos un ejemplo bien simple, supongamos que quiero poner un botón en la pantalla, dicho boton debe mostrar en su texto las veces que ha sido presionado.

var
  Boton;
  
  
Boton = React.createClass({
  getInitialState: function() {
    return { cantidad: 0 };
  },

  render: function() {
    return (<button type="button" onClick={this.aumentaCantidad}>Presionado {this.state.cantidad} veces</button>);
  },
  
  aumentaCantidad: function(evt) {
    this.setState({cantidad: this.state.cantidad + 1});
    evt.preventDefault();
  }
});

React.render(<Boton/>, document.getElementById('container'));

Ver en JSBin

Veamos varios elementos:

  • Un componente en React esta conformado por un diferentes funciones que se ejecutan en un ciclo de vida del componente. Ej: render, getInitialState, ver mas
  • Los componentes pueden o no tener un estado. (Componentes sin estado se les llama puros))
  • Pueden tener funciones adicionales para modificar dicho estado.
  • Para utilizarlos se instancia el componente y se ubica en un contenedor dentro de la página web.
  • Se utiliza JSX como forma de darle mas claridad al código (JSX es muy similar a XML y se embebe en el codigo Javascript con determinadas reglas que deben cumplirse)

Si queremos reutilizar el componente simplemente debemos instanciarlo y ubicarlo en otro contenedor. Ejemplo Multiples Componentes Cada instancia tiene su propio estado.

Especificaciones de Componentes.

Los principales son:

render(): La función render debe retornar un solo objeto de representacion de la interfaz <div/> o React.DOM.div() o un componente definido por ti. Tambien se puede retornar null o undefined para no mostrar ninguna interfaz. Un detalle importante es que en esta función no se puede modificar el estado del componente.

getInitialState(): Se ejecuta una sola vez al inicio de montarse el componente en la pantalla y debe retornar el estado inicial de nuestro componente mendiante un objeto javascript.

propTypes: es un objeto que indica los tipos de las propiedades que recibe el componente en su instanciacion.

Otras: getDefaultProps, mixins, statics, displayName

Funciones del Ciclo de Vida

Estas funciones son ejecutadas en varios momentos del ciclo de vida del componente.

componentDidMount(): Se ejecuta una sola vez cuando el componente se monta en la página. Es el lugar ideal para ejecutar código javascript de integración con otras librerías, establecer timers, etc.

componentDidUpdate(): Se ejecuta cada vez que el componente se refresca y se ejecuta la función render

Otras: componentWillMount, componentWillReceiveProps, shouldComponentUpdate, componentWillUpdate, componentWillUnmount.

Funciones de Operación

Estas funciones permiten cambiar el estado del componente o forzar que se refresque.

setState(): Permite cambiar el estado actual del componente, forzando con el mismo que se intente realizar un repintado del mismo de acuerdo al estado que se cambie. Adicionalmente se le puede especificar una función de callback para una vez termine el cambio de estado poder realizar operaciones.

forceUpdate: Fuerza el repintado del componente manteniendo el estado anterior.

Otras: replaceState, getDOMNode, isMounted, setProps, replaceProps

Las funciones y metodos que he descrito son las que más he usado, normalmente son las esenciales para cualquier componente.

Ejemplo 2:

Crear una aplicación que simule una lista de cosas por hacer es un ejemplo muy tipico. En nuestro demo crearemos 3 componentes, TodoList, TodoItems y TodoInput:

  • TodoList sera el componente primario agrupara toda la funcionalidad.
  • TodoItems solo mostrará el listado de items.
  • TodoInput contendrá el formulario para agregar nuevos items.

var
  TodoItems,
  TodoInput,
  TodoList;
  
TodoList = React.createClass({
  propTypes: {
    todos: React.PropTypes.array
  },

  getInitialState: function() {
    return { todos: this.props.todos || [] }
  },
  
  addTodo: function(item) {
    this.setState({todos: this.state.todos.concat([item])});
  },

  render: function() {
    return (
      <div>
        <h3>TODO List</h3>
        <TodoItems items={this.state.todos}/>
        <TodoInput addTodo={this.addTodo}/>
      </div>
    );    
  }
});

TodoItems = React.createClass({
  propTypes: {
    items: React.PropTypes.array.isRequired
  },
  
  render: function() {
    var
      createItem;
      
    createItem = function(item, index) {
      return (
        <li key={index}>{item}</li>
      );
    };
    return <ul>{this.props.items.map(createItem)}</ul>;
  }
});

TodoInput = React.createClass({
  getInitialState: function() {
     return {item: ''};
  },
  
  onChange: function(e) {
    this.setState({
      item: e.target.value
    });
  },
  
  handleSubmit: function(e) {
    e.preventDefault();
    this.props.addTodo(this.state.item);
    this.setState({item: ''}, function() {
      React.findDOMNode(this.refs.item).focus();
    });
  },
  
  render: function() {
    return (
      <form onSubmit={this.handleSubmit}>
        <input type="text" onChange={this.onChange} value={this.state.item}/>
        <input type="submit" value="Add"/>
      </form>
    );
  }
});

React.render(<TodoList todos={['red','blue']}/>, document.getElementById('container'));

Ver en JSBin

Como ven es un ejemplo sencillo y funcional, siguiendo el patron de componentizar podemos ir tan abajo como quisieramos. Por ejemplo en el ejemplo del TODO List podriamos haber agregado un componente más: TodoItem para cada elemento y en cada uno de ellos implementar algun tipo de función de completamiento para brindar la funcionalidad de que cumplimos con alguna de las tareas de la lista. HTML de esta forma se convierte en solo la forma de representar algunos bits de datos. Lo cual hace React independiente del DOM de HTML y funcional en entornos donde este no existe. El mejor ejemplo de esto es react-native una librería que nos permite crear aplicaciones móviles con rendimiento nativo utilizando Javascript.

Muchas otras tecnologías estan surgiendo del ecosistema React, ImmutableJS, Flux, GraphQL, StyleSheets. Podemos ganar muchísimo en productividad y sencillez implementando interfaces de usuario legibles y faciles de mejorar o corregir en el caso de errores.

Comments

comments powered by Disqus