Daniele Irsuti - Frontend developer

Redux o Context, che usare?

Creare componenti in React è facile. Il problema è scegliere il componente a cui affidare alcune logiche importanti. Come spesso ho letto sulla documentazione ufficiale e su stackoverflow, è bene non esagerare con i componenti stateful perché in termini prestazionali questo può presentare un conto (alle volte salatissimo) a lungo termine. Optando per questa scelta il problema che si para davanti è il seguente:

  • Componente <A /> detiene le logiche da distribuire ai componenti figli;

    • Componente <B /> figlio di <A /> deve smistare alcuni handler sui propri componenti;
    • Componente <C />, <D /> hanno bisogno degli handler provenienti da <A /> smistati da <B />;

      • Potremmo andare all’infinito.

E’ già abbastanza palese dove voglio arrivare: questo tipo di architettura soffre di una problematica chiamata prop drilling. Per risolvere ci viene in soccorso la context API messa a punto da React, qualcosa che permette allo sviluppatore di passare da <A /> a <C /> o <D /> senza passare da <B />. In realtà nella casistica appena mostrata sarebbe ancora accettabile ovviare senza la context API, ma non vorrei dilungarmi inutilmente.

La context API risulta perfetta per la creazione di componenti generici o librerie, perché la problematica è legata a componente genitore - figlio - nipote - pronipote e non vi è alcuna necessità di rendere uno state accessibile a tutti i componenti dell’intera applicazione. Cosa assai diversa appunto, è distribuire oggetti su aree diverse di un’applicazione. La problematica che nella mia esperienza ho riscontrato è che più l’applicazione cresce e più si perde il controllo dei cambiamenti di stato dei componenti. Una cosa che più tra tutte sta nelle priorità di un buon sviluppatore è avere ben chiaro cosa diavolo succede ad ogni cambiamento di stato.

La risposta a quest’altra problematica è Redux.

Un po’ d’ordine con Redux

Redux è una libreria che si occupa di gestire tanti state, detti reducer, centralizzati in uno store (ossia un oggetto che li contiene tutti, separandone le logiche) condiviso con l’intera applicazione e si rivela particolarmente utile per diversi aspetti quali debugging, maggiore astrazione e test separati.

come funziona redux

Per poter utilizzarlo all’interno di un progetto in React viene utilizzato il modulo react-redux oltre a redux, un HOC (high order component) che si occupa di mettere in comunicazione lo store con il component attraverso l’apposita funzione connect che accetta come argomento le due funzioni mapStateToProps e mapDispatchToProps, rispettivamente: “mappa lo state di redux e usale come props del componente”; “mappa i dispatcher di redux come props del componente”.

Con questo non si preclude allo sviluppatore di optare per gli state locali, anzi, è sempre bene tenere tutto il più atomico possibile. Redux non si sostituisce agli state in tutti i componenti dell’applicazione (una cosa che tendenzialmente ho visto spesso in alcuni progetti), ma deve essere utilizzato unicamente per gestire dati condivisi con molti componenti, indipendentemente dal tipo di relazione.

Un caso d’uso comune: dopo l’autenticazione ho bisogno delle informazioni dell’utente autenticato ( es: avatar, nome ) in più parti della mia applicazione. Lo store in questo caso è il più indicato a mantenere questo tipo di informazioni.

Mannaggia quanto è verboso Redux…

E’ vero, si scrive molto ma è un compromesso che bisogna accettare (o pretendere!) ad occhi chiusi in un’applicazione medio grande specie se in team con più persone. Idealmente si potrebbe pensare ad un approccio più test driven, con una risorsa preposta a svilupare i servizi con Redux (action , reducer ed eventualmente saga o action creator) poi testarli e infine pubblicarli.

You Might Not Need Redux - Dan Abramov, co-fondatore di Redux: Link

Conclusioni

PRO di Redux

  • Con Redux hai una maggiore testabilità: è possibile testare lo store indipendentemente da tutta l’applicazione isolandolo;
  • Con Redux puoi dividere i compiti: in un progetto medio-grande può esserci una persona preposta alla creazione di action, reducers e quant’altro;
  • Con Redux hai un livello di astrazione che ti permette di cambiare le API senza stravolgere la logica nei component;
  • Con Redux puoi gestire gli errori automatizzando un sistema di bug report (senza entrare nel merito del component) creando un middleware per Redux ad-hoc

Contro di Redux

  • Evitalo come la peste se lavori in un progetto piccolo e non hai la necessità di gestire molti dati da condividere su più parti dell’applicazione;
  • E’ verboso;
  • Inficia negativamente sulle performance

La documentazione ufficiale: https://reactjs.org/docs/context.html#when-to-use-context

Qui un articolo interessante: https://daveceddia.com/context-api-vs-redux/

Qui una discussione sui pro e i contro: https://stackoverflow.com/questions/49568073/react-context-vs-react-redux-when-should-i-use-each-one