Redux

“un contenitore di stati deterministico(prevedibili) per le applicazioni JS”.

nasce per risolvere un problema: la gestione dello stato.

L’architettura Redux ha il compito di consentire la gestione dello stato di un’applicazione mediante passaggi definiti.

Lo stato dell’applicazione

lo stato di un sistema (per esempio di un’applicazione) è l’insieme delle condizioni interne(dati in senso lato) in uno specifico istante che determinano il risultato delle interazioni con l’esterno, l’insieme delle informazioni che determinano l’output in corrispondenza di un dato input in uno specifico istante.

in una Single Page Application(SPA) lo stato è

  1. dati provenienti dal server e memorizzati in una cache locale;
  2. dati generati dall’applicazione stessa che devono essere inviati al server;
  3. dati che devono rimanere in locale per rappresentare ad esempio la situazione corrente dell’interfaccia utente o le preferenze espresse dall’utente.

La gestione di questi dati è complessa

  1. per la mole di dati in sé,
  2. possono variare (interazioni con l’utente, interazioni con il server) e richiedono un repaint dell'interfaccia.
  3. il risultato delle modifiche avviene in maniera asincrona

in debug, è problemetico ricreare una situazione tale da consentire un’analisi del problema(deterministico).

tradizionalmente la gestione dello stato è realizzata attraverso la separazione delle competenze nel pattern Model-View-Controller, lo stato corrente (il modello) dalle funzionalità che lo modificano(controller) e lo presentano all’utente(view), ma non risolvono del tutto il problema, dal momento che le modifiche al modello non sono deterministiche e riproducibili.

principi fonamentali Redux

la causa della complessità nella gestione dello stato di un’applicazione in due elementi: modificabilità e asincronicità. La soluzione proposta da Redux è rimuovere queste due caratteristiche, basandosi su tre principi fondamentali:

  1. esiste una singola fonte di verità: lo stato dell’intera applicazione è memorizzato in un unico oggetto
  2. lo stato è in sola lettura:

non è possibile modificare direttamente le informazioni, ma per farlo è necessario passare tramite azioni esplicite(reducers)

  1. le modifiche allo stato vanno fatte con funzioni pure: lo stato viene sostituito da un nuovo stato generato da funzioni senza side effects che hanno come unico input lo stato precedente

Le possibili modifiche(transizioni) allo stato sono determinate dalle Action implementate, ciò assicura che lo stato non sia modificabile arbitrariamente.

i benefici

  1. predicibilità delle transizioni di stato
  2. transazioni riproducibili
  3. semplifica scrivere unit test per i reducers (Controller)
  4. semplifica implementare "undo / redo" (see Memento)

Redux costringe ad organizzare il codice seguendo uno specifico pattern, il che definisce indirettamente uno standard di codifica per il team.

limiti

non è detto che la nostra applicazione debba utilizzare Redux. prezzo in termini di:

  1. indirezione/complessità accidentale(8 files collegati a un singolo concetto Model)
  2. memoria utilizzata
"so we’ve got the methods for this concept in one module, and the data they operate on in another module.”
So yeah, you’re basically using singletons to modify global state. Martin Fowler just had a heart attack.

componenti e interazioni

passi per modificare llo stato:

  1. individuata una Action, eventualmente generata tramite un Action creator
  2. Action inviata allo Store tramite un Dispatcher
  3. nello Store, un Reducer sostituisce allo stato corrente il nuovo stato calcolato con i paramatri in Action

componenti coinvolti:

  1. State: costituito da un oggetto con struttura arbitraria; una struttura ad albero o altro se necessario (Singleton)
  2. Store: consente l’accesso e la manipolazione dall’esterno; esiste un unico store per la sua gestione (Singleton)
  3. Reducer: una normale funzione JS che prende lo stato corrente e un’azione e restituisce lo stato successivo; è fondamentale che sia una funzione pura, cioè una funzione senza side effects, dato uno specifico input deve restituire sempre lo stesso output(questo non è forzabile alivello di linguaggio o lib come in Elm/Haskell).
  4. Action (Azione): oggetto JS in grado di cambiare lo stato corrente, Redux non impone regole alla struttura della Action, anche se per convenzione ha almeno una proprietà `type` e `payload` contiene i parametri
  5. Action creator: può essere utile definire una funzione che genera un’azione in base a determinati parametri
  6. Dispatcher: ha il compito di inviare una Action allo Store il quale, tramite un opportuno Reducer, effettua la transizione di stato