Qualsiasi sia la libreria o il framework front-end che utilizziate, se è basato su un’architettura a Componenti (come Angular, React, Vue…) sicuramente vi sarete imbattuti in queste terminologie: stateless, stateful, dumb, smart, container, presentational. Conoscerle e capirne le differenze non è solo importante, è fondamentale! E purtroppo, si tende a far confusione e a pensare che un termine ne indichi un altro… In effetti, online c’è molta confusione. Facciamo chiarezza!

Stateless vs Stateful

Un componente stateless è un componente senza uno stato interno. Cos’è uno stato? Dipende, in Angular può essere rappresentato da delle proprietà interne alla classe, in React potrebbe essere rappresentato dalla proprietà this.state o da un hook useState(), in StencilJS può essere indicato da un decoratore @State, e così via… Diciamo che il componente ha uno stato interno quando può cambiare comportamento senza che gli venga passata una proprietà o un input dall’esterno.

Prendiamo un caso semplice: un componente Accordion.

Come funziona un accordion? L’utente clicca su un tab e quel tab viene aperto, diventando visibile. Lo stato interno di un accordion quindi, potrebbe essere banalmente l’indice del tab aperto al momento (o i tab, se ci lascia tenerne aperti più di uno).

Quindi, un componente accordion totalmente stateless, non dovrebbe occuparsi di cambiare il suo stato autonomamente, ma dovrebbe affidarsi solamente alle istruzioni del componente padre:

Come avrete capito, questo è un comportamento scomodo, e infatti praticamente tutti gli accordion che troverete in librerie di componentistica sono stateful, ovvero si occupano loro di modificare il proprio stato quando l’utente clicca su un tab.

Attenzione però: un componente stateful è una buona cosa (non pregiudica in alcun modo la qualità del vostro codice, se è scritto bene), ma se vogliamo fare le cose fatte bene, dobbiamo fare in modo che quando lo stato interno cambia, il componente notifichi il suo padre con un evento! In questo modo, possiamo continuare a manovrarlo dall’esterno anche se il suo stato può cambiare autonomamente.

Quindi, come abbiamo detto, va benissimo creare dei componenti stateful, ma fatelo solo se serve rendere un componente autonomo. Potrebbe salvarvi la vita in alcuni casi, risparmiando centinaia di righe di codice ripetute, ma ricordate che un componente stateless è tipicamente più performante, più facile da capire, e in gergo si dice diventi più predictable, ovvero dato un cambiamento è più facile capire come cambia il risultato.

Un componente stateless è quindi da preferire in molti casi, ma questa è solamente una regola generale. Non fissatevi su questo punto facendone la vostra missione di vita: se è logico che un componente mantenga un proprio stato interno, non c’è nulla di male. Anzi, il voler a tutti costi creare solamente componenti stateless può essere dannoso e può rendere la vostra applicazione più complessa di quanto serva.

Dumb vs Smart

Qui c’è molta confusione, quindi chiariamo cosa non vogliono dire queste terminologie: dumb non indica un componente stateless e smart non indica un componente stateful.

Possiamo tradurli con “stupido” e “intelligente”, ma stiamo indicando un’altra cosa. Un componente dumb (stupido) è un componente che non ha dipendenze dall’esterno. Un componente smart (intelligente) invece ha delle dipendenze!

L’esempio classico è quello di uno State Manager (come Redux): tipicamente, per ogni rotta c’è un componente smart che si interfaccia con lo stato applicativo (tramite Dependency Injection in Angular, ad esempio), che si occupa di “prelevare” lo stato attuale per passarlo ai componenti figli e ascolta gli eventi emessi dai componenti figli per cambiare quello stato.

Di conseguenza, è buona prassi che tutti i componenti figli di questo componente siano dumb, ovvero che si lascino guidare dal padre e non vadano a toccare lo stato. Se succedesse, avremmo una applicazione molto difficile da manutenere, con comportamenti inconsistenti (diventerebbe difficile capire chi modifica lo stato).

Esempio di parte di un’applicazione. Come vedete, non c’è differenza nella visione generale fra Stateful e Stateless: il fatto che l’Accordion abbia uno stato interno non pregiudica l’architettura se rimane controllabile dall’esterno!

Può succedere che un componente smart abbia la necessità di avere anche uno stato interno, a prescindere da quello globale che prende dallo State Manager: magari abbiamo scelto di non tenere nello stato globale qualche informazione, come un form, che potrebbe essere pesante o inutile da serializzare (è solo un esempio). Per questo si tende spesso a far confusione, pensando che stateful sia sinonimo di smart: avete capito che non è così!

Ora la nota finale: container e presentational non sono altro che due modi alternativi di chiamare i componenti smart e dumb, nulla di più! Spesso si preferisce queste nomenclature (io ad esempio le preferisco) perché esprimono con maggior chiarezza l’intento del componente: il container contiene i figli, mentre i presentational presentano le informazioni nella schermata.

Conclusioni

Ricapitolando, in un tipico scenario di architettura a componenti, queste sono le categorie di componenti che possiamo trovare:

  • Componente Stateless: non ha uno stato interno, viene guidato dal padre che gli fornisce tutto ciò di cui ha bisogno in ogni momento.
  • Componente Stateful: può essere guidato dal padre, ma ha anche un suo stato interno per comodità. Ma è bene che questo stato interno, quando cambia, venga anche passato al padre, altrimenti diventa fuori controllo.
  • Componente Dumb o Presentational: non ha dipendenze e si occupa di mostrare delle informazioni nel template. Tipicamente è stateless, ma non è sempre vero.
  • Componente Smart o Container: ha delle dipendenze esterne (es. Redux), organizza la schermata manipolando dei componenti dumb, è incaricato di passare lo stato ai figli e di utilizzare gli eventi dei figli per modificare lo stato.

Ti è piaciuto l’articolo? Condividilo!

Rilasciare risorse gratuite non è facile: un sacco di tempo vola fra la ricerca dell’idea, la stesura, la preparazione di codice funzionante e la revisione. Se ti piace ciò che facciamo, condividi l’articolo: nel peggiore dei casi ti daranno del secchione!

Ti interesserà anche…

Callbacks e Higher Order Functions

Oggi esploriamo due concetti chiave nel mondo della programmazione, specialmente della programmazione in JavaScript: le funzioni di callback e le Higher Order Function! Sono concetti molto legati fra loro, ma…

Iscriviti alla nostra newsletter!

Rimani aggiornato per quando rilasceremo nuovi articoli, nuovi corsinuove promozioni e nuove risorse gratuite. Ti promettiamo che useremo la tua email con prudenza, e non la condivideremo con nessuno senza il tuo consenso!

Abbiamo a cuore la tua privacy. Niente spam. Leggi la nostra privacy policy qui.

Menu