Introduzione a MobX

MobX è una nuova libreria di “State Management” per applicazioni Javascript. Si pone quindi come concorrente di altre librerie come Flux e Redux. Il concetto teorico che c’è alla base di MobX è il “Reactive programming”: paradigma basato sul propagarsi automatico del cambiamento. Prendiamo ad esempio una classica assegnazione di una variabile.

const a = b + c;

In questo caso sappiamo benissimo che al cambiare di b o c il valore di a rimane invariato. Se invece utilizziamo un foglio di calcolo e all’interno di una cella inseriamo la seguente formula:

=B1+C1

il valore della cella viene aggiornato automaticamente al cambiare di B1 o C1. Questo è quello che avviene normalmente quando si utilizzano tecniche di Reactive programming. Se volessimo semplificare al massimo potremmo dire un’applicazione basata su questo paradigma è un’applicazione basata in maniera massiva sul pattern Observer.

meme

Reactive programming in un meme

Scendiamo ora nel dettaglio di questa libreria. Sulla documentazione ufficiale di MobX troviamo i seguenti elementi cardine.

Observable State

Il cuore pulsante di MobX è il concetto di “stato osservabile”, la caratteristica principale di MobX è quella infatti di poter rendere qualsiasi oggetto e/o classe JavaScript un observable. Vedremo più avanti tramite un esempio che questa cosa avviene in maniera davvero semplice.

Computed values

Un computed value è un valore che viene automaticamente ricalcolato al variare dello stato. Ritornando all’esempio dello spreadsheet il valore della cella è un computed value mentre le celle B1 e C1 sono l’observable state. Al variare del secondo, il primo viene ricalcolato.

Reactions

Simili ai computed values ma invece che produrre nuovi valori producono esclusivamente side-effect come logging, o render della view.

Actions

Le actions sono le operazioni che modificano lo stato. Al contrario di altre API come Redux, in MobX le azioni non sono parte integrante del framework. Potete infatti cambiare direttamente le proprietà del modello, oppure utilizzare un sistema ad eventi, aumentando la complessità ma anche la robustezza dell’applicazione.

Possiamo schematizzare quanto detto fino ad ora con il seguente grafico:

schema

Schema di MobX

Let’s Code

Proviamo ora a mettere a fuoco quanto detto finora con un esempio: implementeremo una piccola applicazione React che stampa un elenco di utenti presi dai servizi REST messi a disposizione da randomuser.me. Iniziamo subito dallo stato dell’applicazione, che abbiamo racchiuso in una classe Ecmascript6.

Il decorator @observable trasforma per l’appunto le proprietà loading e users in observables, uno dei quali aggiornerà automaticamente il computed value numberOfUsers, definito tramite il decorator @computed. Vediamo ora come utilizzare lo stato appena analizzato in una chiamata REST.

Notate che utilizziamo gli observable di AppState, ma questi vengono utilizzati in maniera trasparente dall’applicazione, che ne può modificare i valori come per qualsiasi altro oggetto. sotto il cofano MobX modifica i setter delle proprietà marchiate come observable tramite il metodo Object.defineProperty.

Vediamo ora come collegare MobX alla nostra applicazione React. Il primo step è creare un’istanza AppState e passarlo come props al nostro unico componente chiamato App.

Prima di passare al contenuto di App soffermiamoci un attimo sulla funzione autorun. Questa funzione è il nostro primo esempio di reaction, infatti rimane in ascolto del cambiamento di numberOfUsers e lo stampa in console. Notate inoltre che il decorator @computed ha trasformato numberOfUsers da metodo a proprietà. Completiamo il flusso con il codice del componente App:

Abbiamo accennato in precedenza che il render in un’applicazione MobX è considerata una reaction scatenato da un’observable. Questa cosa viene messa in atto dal decorator @observer, importato dal pacchetto mobx-react: binding ufficiale di MobX per il framework di Facebook. In pratica il decorator fa in modo che ogni cambiamento su AppState venga automaticamente renderizzato a schermo, in maniera del tutto analogo al metodo setState di React.

Conclusioni

Quando usare quindi MobX? Per capirlo proviamo a paragonarlo a quello che considero il suo rivale attuale: Redux. Rispetto a Redux ha un grosso vantaggio: l’assenza del boilerplate tipico di Redux e delle altre declinazioni di Flux. Rispetto a Redux però ha due grossi svantaggi, il primo è che vi obbliga a sporcare il modello. In Redux la vostra logica è racchiusa in Actions e Reducers, che sono formati in gran parte da codice JavaScript che non dipende da framework. In questo caso invece siete portati a “sporcare” la vostra logica con i decorator di MobX. L’altro problema che vedo è l’assenza di constraints, qui non avete un unico store e le action che modificano lo stato, ma potete avere moltissimi store modificati da chiunque.

Il mio consiglio è quindi quello di utilizzare MobX in applicazioni di dimensioni medio/piccole dove l’assenza di boilerplate vince sugli altri svantaggi, mentre negli altri casi opterei per un più robusto Redux. Tenete presente però che entrami i framework fanno sì che i componenti React dipendano esclusivamente dalle props. Quindi in ottica sacrificale è possibile iniziare lo sviluppo con MobX e quando (soprattutto se) l’applicazione cresce passare a Redux con relativamente poco sforzo.

Se siete interessati al codice, in questo repository GitHub trovate tutto il codice visto in questo post. È inoltre presente un esempio di utilizzo di MobX in ambiente AngularJS. La gestione degli observable di MobX è un ottimo modo per evitare $watch e $broadcast che rischiano di far diventare il vostro codice “spaghettoso”.

La canzone di questo post è La Bestia Nel Grano tratto dall’ultimo album di Vinicio Capossela intitolato Canzoni Della Cupa. Buon Ascolto.

Flattr this!

Pubblicato in Javascript Taggato con: , ,

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.