En este post hablaremos de una librería muy útil llamada Mobx que entre otras cosas nos facilita un poco el desarrollo en cuanto a la comunicación entre componentes se refiere, es decir, ya hemos visto un poco como comunicarnos de un componente a otro para realizar alguna modificación en alguna propiedad, pues bien Mobx nos facilita este planteamiento (entre otras cosas claro ;) ). Si queréis algo más de información aqui tenéis la página oficial de Mobx
Instalación
Para instalar mobx usaremos nuestro magnífico npm:
npm install mobx mobx-react --save
Esto nos instalará en el proyecto los módulos de NodeJS necesarios para poder trabajar con Mobx
Usando Mobx
Bien vamos a empezar a partir de la estructura de proyecto que teniamos en el post anterior (tras ejecutar nuestro create-app....).
Vamos a trabajar sobre el fichero App.js que es el componente que se esta rendeando por defecto, pero vamos a cambiarlo un poco y asi vemos que realmente estamos en este punto, vamos a cambiar la frase que aparece debajo de Welcome to React para indicar que trabajaremos despues de esa linea:
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
class App extends Component {
render() {
return (
<div className="App">
<div className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h2>Welcome to React</h2>
</div>
<p className="App-intro">
We started working below this line
</p>
</div>
);
}
}
export default App;
Tras guardar, automáticamente tendriamos algo similar a
Bien ya sabemos donde estamos, ahora haremos un ejemplo simple para ver que es lo que conseguimos con Mobx, vamos a mostrar un número y este aumentará cuando pulsemos un botón.
Primero mostremos nuestro número, en un principio es algo sencillo que ya hemos visto no?, creamos un componente nuevo y lo indicamos en el componente que se esta renderizando como principal no??...... si esa es una opción pero al final estaríamos haciendo lo mismo que ya hemos visto y entonces para que queremos mobx no??. Pues bien la teoría del componente es válida a medias, vamos a crear una clase y en esta tenemos que importar extendObservable de la librería de mobx. Yo le he puesto el nombre FirstMobxClass.js y esto es lo que ponemos
import {extendObservable} from 'mobx'
class FirstMobxClass {
constructor(){
//Recibe el objeto a observar y las propiedades
extendObservable(this,{
number: 1
})
}
}
//Creamos una nueva instancia de nuestra clase,la almacenamos
// y la exportamos para que se tenga acceso desde fuera
//de esta clase
var numberMobxClass = new FirstMobxClass();
export default numberMobxClass;
Con esto tendríamos una variable con una propiedad number que deberíamos poder usar. Para ello volvamos a nuestra clase App.js y ponemos lo siguiente:
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
//Our imports
import numberMobxClass from './FirstMobxClass';
class App extends Component {
render() {
return (
<div className="App">
<div className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h2>Welcome to React</h2>
</div>
<p className="App-intro">
We started working below this line
</p>
<h2>{ numberMobxClass.number }</h2>
</div>
);
}
}
export default App;
Para diferenciar los imports que ya teniamos de los nuevos he indicado el comentario our imports. Como véis lo que importamos es nuestra variable del fichero con nombre FirstMobxClass y para usarlo nos valemos de las magias del lenguaje JSX y con poner
<h2>{ numberMobxClass.number }</h2>
Ya tendríamos nuestra linea con el número que hemos puesto
Lo siguiente será crear nuestro botón, en este caso seguimos la teoría inicial de los componentes que ya sabíamos, me refiero a que lo creamos como un componente normal. Creamos el fichero IncreaseNumber.js
import React, { Component } from 'react';
class IncreaseNumber extends Component {
render(){
return(
<button>Increase Number</button>
)
}
}
export default IncreaseNumber;
De momento nada nuevo, para verlo lo importamos en App.js y lo ponemos a continuación, es decir ahora en App.js debajo de Our imports añadimos un import más debajo del numberMobxClass
//Our imports
import numberMobxClass from './FirstMobxClass';
import IncreaseNumber from './IncreaseNumber';
Y luego debajo de nuestro número le ponemos el botón
<h2>{ numberMobxClass.number }</h2>
<IncreaseNumber/>
Y al guardar ya veríamos nuestro botón
Pero aunque pulsemos de momento no hace nada no??....continuemos ahora para añadirle funcionalidad. Al igual que haciamos antes necesitamos un método que haga que aumente nuestro número, y al igual que haciamos antes lo mejor es que lo creemos en el mismo punto que donde tenemos nuestra propiedad. Esto es tan simple como sumarle 1 al número, es decir añadimos a nuestra clase FirstMobxClass el método increase
class FirstMobxClass {
constructor(){
//Recibe el objeto a observar y las propiedades
extendObservable(this,{
number: 1
});
}
increase(){
this.number = this.number + 1;
}
}
Ya tenemos nuestro método ahora indiquemosle a nuestro botón que tiene que usarlo, probemos a ponerlo directamente con un onClick en el componente IncreaseNumber
import React, { Component } from 'react';
import numberMobxClass from './FirstMobxClass';
class IncreaseNumber extends Component {
render(){
return(
<button onClick={numberMobxClass.increase} >Increase Number</button>
)
}
}
export default IncreaseNumber;
Si os fijáis hemos importado nuestra clase numberMobxClass y hemos usado nuestro método increase directamente en el onClick, bien si guardamos vemos que la página renderiza bien pero que pasa si pulsamos.......UPSSS!!!
Vemos que nos sale este error, y eso es como os podéis imaginar que this no tiene nada, diréis "pues entonces podemos ponerle un bind igual que haciamos antes y ya esta", bueno pues vamos a probarlo a ver que pasa y de paso le ponemos al método increase un log para ver que tiene this.
El método increase ahora quedaria así
increase(){
console.log(this);
this.number = this.number + 1;
}
Y nuestro onClick
<button onClick={numberMobxClass.increase.bind(this)} >Increase Number</button>
Veamos que pasa cuando pulsamos
No nos da error pero si nos fijamos en lo que nos devuelve nuestro log, la propiedad number es NaN y eso ¿por qué? Pues porque realmente estamos pasando con bind el this de nuestro componente IncreaseNumber el cual no tiene esa propiedad, hagamos un pequeño ejemplo para verlo, creemos una propiedad en el componente IncreaseNumber como hemos visto en anteriores post y veamos el log ahora.
El componente IncreaseNumber quedaria asi
class IncreaseNumber extends Component {
constructor(){
super();
this.test = 2;
}
render(){
return(
<button onClick={numberMobxClass.increase.bind(this)} >Increase Number</button>
)
}
}
Y al pulsar tenemos este log
Si os fijáis number sigue siendo NaN pero sin embargo tenemos nuestra propiedad test con el valor que hemos puesto, entonces quiere decir que estamos pasando el contexto del componente IncreaseNumber.... y entonces como lo hacemos??...Es más fácil de lo que parece, onClick espera una función no?, pues simplemente usemos una función que cada vez que se use esta "llame" a nuestro método increase (al estilo típico de la programación habitual)
Con esta teoría nuestro onClick quedaría así
<button onClick={() => numberMobxClass.increase()} >Increase Number</button>
Veamos lo que tiene this ahora
Anda!! Ahora nuestro number si aumenta pero..... en nuestra página no se ve.....y eso?? bueno la explicación es sencilla no estamos "observando" la propiedad para que responda los cambios y como hacemos eso?...Fácil, importamos observer de la libreria mobx-react y le indicamos que observe donde estamos renderizando, es decir en App.js, por lo que el componente quedaría asi
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
//Our imports
import numberMobxClass from './FirstMobxClass';
import IncreaseNumber from './IncreaseNumber';
import { observer } from 'mobx-react';
class App extends Component {
render() {
return (
<div className="App">
<div className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h2>Welcome to React</h2>
</div>
<p className="App-intro">
We started working below this line
</p>
<h2>{ numberMobxClass.number }</h2>
<IncreaseNumber/>
</div>
);
}
}
export default observer(App);
Y voilá ya tenemos nuestro numero aumentando en nuestra página
Espero que quede más o menos claro como estamos usando la característica observable que nos proporciona Mobx, que realmente nos facilita un poco estar pendiente de los estados o cambios de nuestras propiedades.
En el siguiente post seguiremos viendo que más cosas podemos hacer con Mobx, nos vemos, un abrazooorrrrrr








