Abbiamo visto finora come definire la struttura dello stato della nostra applicazione, come definire le azioni che determinano le transizioni di stato e come effettuare le transizioni da uno stato all'altro mediante i reducer. Allo stato attuale non abbiamo utilizzato nulla della libreria di Redux se non il pattern architetturale proposto. Proviamo quindi ora a mettere tutto insieme per darlo in pasto a Redux che si occuperà della gestione vera e propria dello stato della nostra applicazione. Il componente che prenderà in carico questo delicato compito è lo Store.
Creare lo Store
Creiamo quindi il nostro Store come mostrato di seguito:
import { createStore } from 'redux'
let store = createStore(todo);
Abbiamo creato il nostro Store invocando la funzione createStore()
con il reducer todo()
come parametro.
Può essere utile creare lo Store passando uno stato iniziale. In questo caso passiamo lo stato come secondo parametro della funzione createStore()
:
import { createStore } from 'redux'
const initialState = { todoList: []};
let store = createStore(todo, initialState);
La possibilità di passare uno stato iniziale risulta utile quando si vuole inizializzare l'applicazione con uno stato specifico, ad esempio con informazioni provenienti dal server.
Interagire con lo stato
Lo Store ci mette a disposizione alcune funzionalità per interagire con lo stato. La prima funzionalità riguarda l'invio di azioni che possono far cambiare lo stato corrente. Per inviare allo Store un'azione utilizziamo il metodo dispatch(). Nel seguente esempio inviamo allo store l'azione che permette di aggiugere una nuova attività nella nostra lista:
store.dispatch(addAction("Fare la spesa"));
Abbiamo passato al metodo dispatch()
l'azione creata dall'Action creator addAction()
. Naturalmente avremmo potuto passare direttamente l'azione, ma per le considerazioni viste prima, può essere opportuno utilizzare un Action creator.
All'interno dello Store l'azione viene passata al reducer, il quale sostituisce lo stato corrente con quello individuato in seguito all'analisi del tipo di azione passata.
Come facciamo a questo punto ad accedere al nuovo stato generato dall'invio dell'azione? Redux non permette di accedere direttamente allo stato dell'applicazione, ma possiamo ottenere lo stato corrente tramite il metodo getState():
console.log(store.getState());
//output: { todoList: [{id: 1, task: "Fare la spesa" }]}
L'uso di getState()
, tuttavia, può risultare poco pratico dal momento che la modifica dello stato dell'applicazione potrebbe interessare non solo il componente che ha inviato un'azione allo Store, ma anche altri componenti della nostra applicazione. Questo è uno dei motivi per cui lo Store ci mette a disposizione il metodo subscribe() che ci consente di ricevere notifiche sulle transizioni di stato seguendo il design pattern Publisher/Subscriber.
Possiamo quindi intercettare i cambiamenti di stato registrando un listener come quello del seguente esempio:
store.subscribe(() => console.log(store.getState()));
In questo modo, quando si verifica un cambiamento di stato e indipendentemente da chi l'abbia generato, scriveremo sulla console il nuovo stato ottenuto.