Cos'è Redux: una guida per designer
Pubblicato: 2022-03-10Hai sentito parlare di Redux? Che cos'è? Niente googlare, per favore!
- "Roba di back-end fantasiosa."
- “Ne ho sentito parlare, ma non so di cosa si tratta. Forse è un framework React?"
- "Un modo migliore per archiviare e gestire gli stati in un'applicazione React."
Ho fatto questa domanda a oltre 40 designer. Quanto sopra sono le loro risposte tipiche. Molti di loro sono consapevoli del fatto che Redux funziona con React e il suo compito è la "gestione dello stato".
Ma sai cosa significa davvero questa “gestione statale”? Sai che il vero potere di Redux è al di là della gestione dello stato? Sai che Redux non richiede necessariamente che React funzioni ? Vuoi unirti alla discussione del tuo team (o almeno alle chat del pranzo) sull'opportunità di utilizzare Redux? Vuoi progettare pensando a come funziona Redux?
Con l'aiuto di questo articolo, vorrei mostrarvi un quadro completo di Redux : cosa può fare, perché fa le sue cose, quali sono gli svantaggi, quando usarlo e come si relaziona al design.
Il mio obiettivo è aiutare i designer come te. Anche se non hai scritto una singola riga di codice prima, penso che sia ancora possibile e vantaggioso (e divertente) capire Redux. Aspettati un inglese semplice e scarabocchi: nessun codice o discorsi astratti.
Pronto per il giro?
Cos'è Redux?
Ad un livello molto alto, Redux è uno strumento che gli sviluppatori usano per semplificarsi la vita. Come molti di voi avranno sentito, il suo lavoro è la "gestione dello stato". Spiegherò cosa significa gestione dello stato alcune sezioni più avanti. A questo punto vi lascio con questa immagine:
Perché dovresti preoccuparti?
Redux riguarda più il funzionamento interno di un'app che il suo aspetto. È uno strumento alquanto complesso con una curva di apprendimento ripida. Questo significa che noi, come designer, dovremmo starne lontani?
No. Penso che dovremmo abbracciarlo. Un designer di automobili dovrebbe capire a cosa serve il motore, giusto? Per progettare con successo interfacce per app, i designer dovrebbero anche avere una solida conoscenza delle cose nascoste . Dovremmo imparare cosa può fare, capire perché gli sviluppatori lo usano ed essere consapevoli dei suoi vantaggi e implicazioni.
“Il design non è solo ciò che sembra e si sente. Il design è come funziona."
- Steve Jobs
Cosa può fare Redux?
Molte persone usano Redux per gestire lo stato nelle app React. È il caso d'uso più comune in natura e Redux migliora gli aspetti in cui React non funziona (ancora).
Tuttavia, vedrai presto che il vero potere di Redux va ben oltre. Iniziamo imparando cosa significa veramente la gestione dello stato.
Gestione dello Stato
Se non sei sicuro di cosa significhi questo "stato", sostituiamolo con un termine più generico: "dati". Lo stato è un dato che cambia di volta in volta . Lo stato determina cosa viene visualizzato sull'interfaccia utente.
Cosa si intende per gestione statale? In generale, ci sono tre aspetti dei dati che dovremmo gestire in un'app:
- Recupero e memorizzazione dei dati
- Assegnazione di dati agli elementi dell'interfaccia utente
- Modifica dei dati
Diciamo che stiamo costruendo una pagina di tiro Dribbble. Quali sono i dati che vogliamo visualizzare nella pagina? Includono la foto del profilo dell'autore, il nome, la GIF animata, il numero di cuori, i commenti e così via.
Innanzitutto, dobbiamo recuperare tutti questi dati da un server nel cloud e metterli da qualche parte. Successivamente, dobbiamo effettivamente visualizzare i dati. Dobbiamo assegnare parti di questi dati agli elementi dell'interfaccia utente corrispondenti che rappresentano ciò che effettivamente vediamo nel browser. Ad esempio, assegniamo l'URL della foto del profilo all'attributo src
di un tag img
HTML:
<img src='https://url/to/profile_photo'>
Infine, dobbiamo gestire le modifiche ai dati. Ad esempio, se un utente aggiunge un nuovo commento a uno scatto Dribbble o aggiunge una stella, è necessario aggiornare l'HTML di conseguenza.
Il coordinamento di questi tre aspetti dello stato è una parte importante nello sviluppo del front-end e React ha vari gradi di supporto per questo compito. A volte la struttura integrata in React funziona abbastanza bene. Ma man mano che l'app diventa più complessa, il suo stato potrebbe diventare più difficile da gestire con React da solo. Ecco perché molte persone iniziano a utilizzare Redux come alternativa.
Recupero e archiviazione dei dati
In React, suddividiamo un'interfaccia utente in componenti. Ciascuno di questi componenti può essere suddiviso in componenti più piccoli (vedi “Cos'è React?”).
Se la nostra interfaccia utente è strutturata in questo modo, quando recuperiamo i dati e dove li archiviamo prima di popolare l'interfaccia utente?
Immagina che ci sia uno chef che vive in ogni componente . Recuperare i dati dai server è come reperire tutti gli ingredienti necessari per preparare i piatti.
Un modo ingenuo è recuperare e archiviare i dati dove e quando è necessario. È come se ogni chef esca per comprare verdure e carni direttamente da fattorie lontane.
Questo approccio è uno spreco. Avremmo bisogno di chiamare il server molte volte da molti componenti, anche per gli stessi dati. Gli chef sprecherebbero un sacco di benzina e tempo viaggiando avanti e indietro.
Con Redux, recuperiamo i dati una volta e li archiviamo in una posizione centrale, convenientemente chiamata "store". I dati sono quindi pronti per essere utilizzati in qualsiasi momento da qualsiasi componente. Questo non è diverso dall'avere un supermercato nelle vicinanze dove i nostri chef possono acquistare tutti gli ingredienti. Il superstore invia camion per riportare indietro verdure e carne alla rinfusa dalle fattorie. È molto più efficiente che chiedere ai singoli chef di andare loro stessi nelle fattorie!
Il negozio funge anche da unica fonte di verità. I componenti recuperano sempre i dati dal negozio, non da nessun altro. Ciò mantiene tutto il contenuto dell'interfaccia utente coerente.
Assegnazione di dati agli elementi dell'interfaccia utente
Con solo React, c'è in realtà un modo migliore per recuperare e archiviare i dati. Possiamo chiedere al nostro gentilissimo chef Shotwell di fare la spesa per tutti i suoi amici chef. Avrebbe guidato un camion alle fattorie e avrebbe portato indietro le chicche. Potremmo recuperare i dati da un componente contenitore, ad esempio il componente "Shot" nell'esempio di Dribbble, e utilizzarlo come unica fonte di verità.
Questo approccio è più efficiente del modo ingenuo di recuperare i dati da ogni componente. Ma come fa Shotwell a passare gli ingredienti ad altri chef? Come passare i dati ai componenti che effettivamente rendono gli elementi HTML? Passiamo i dati dai componenti esterni ai componenti interni come il testimone in una staffetta, fino a quando i dati non raggiungono la destinazione.
Ad esempio, l'URL dell'avatar dell'autore deve essere passato da "Shot", a "ShotDetail", a "Title" e infine al tag <img>
. Se i nostri chef abitano in un appartamento, sembra proprio questo:
Per consegnare i dati alla destinazione, dovremmo coinvolgere tutti i componenti sul percorso, anche se non hanno affatto bisogno dei dati. Sarebbe davvero fastidioso se ci fossero molti piani!
E se il superstore effettua consegne porta a porta? Con Redux 1 , possiamo collegare qualsiasi dato a qualsiasi componente, senza influire affatto su altri componenti, in questo modo:
1 Per essere assolutamente precisi, è un'altra libreria chiamata react-redux
che consegna i dati ai componenti React, non Redux stesso. Ma dal momento che react-redux fa solo l'impianto idraulico e le persone usano quasi sempre Redux e react-redux insieme, penso che vada bene includerlo come uno dei vantaggi di Redux.
Nota : nell'ultima versione di React (16.3), c'è una nuova API "contesto" che fa quasi lo stesso lavoro in termini di collegamento dei dati ai componenti. Quindi, se questo è l'unico motivo per cui il tuo team sta usando Redux, prendi seriamente in considerazione l'aggiornamento a React 16.3! Consulta il documento ufficiale per ulteriori informazioni (attenzione: molto codice in anticipo).
Modifica dei dati
A volte la logica dell'aggiornamento dei dati in un'app può essere piuttosto complessa. Potrebbe comportare più passaggi che dipendono l'uno dall'altro. Potrebbe essere necessario attendere le risposte da più server prima di aggiornare lo stato dell'applicazione. Potrebbe essere necessario aggiornare molti luoghi dello stato in momenti diversi e in condizioni diverse.
Può essere opprimente se non abbiamo una buona struttura per tutta questa logica. Il codice sarebbe difficile da capire e mantenere.
Redux ci permette di dividere e conquistare . Fornisce un modo standard per suddividere la logica di aggiornamento dei dati in piccoli "riduttori". Quei riduttori lavorano armoniosamente insieme per completare un'azione complessa.
Tieni d'occhio il recente sviluppo di React, però. Come con l'API "context", potrebbe esserci una nuova API "setState" in una versione futura di React. Semplificherebbe la suddivisione della logica di aggiornamento complessa in parti più piccole. Una volta che questa nuova API sarà disponibile, è possibile che non avrai più bisogno di Redux per gestire questo aspetto della gestione dello stato.
Il vero potere di Redux
Finora, sembra che Redux sia solo un cerotto per React. Le persone usano Redux per migliorare aspetti che React non fa (ancora) bene. Ma React sta recuperando terreno rapidamente! In effetti, Dan Abramov, il creatore di Redux, si è unito al core team di React su Facebook un paio di anni fa. Sono stati impegnati a lavorare sui suddetti miglioramenti a React: API di contesto (rilasciata in 16.3), una migliore API di recupero dei dati (dimostrata a febbraio 2018), una migliore API setState e così via.
Renderà Redux obsoleto?
Indovina un po? Non ti ho ancora mostrato la vera potenza di Redux!
Redux costringe gli sviluppatori a seguire alcune regole rigide, che conferiscono a Redux molta potenza (sì, il potere della disciplina!):
- Tutti i dati (stato dell'applicazione) devono essere descritti in chiaro. Dovresti essere in grado di annotare tutti i dati con una penna su carta.
- Ogni azione (modifica dei dati) deve essere descritta in chiaro. Devi scrivere cosa farai prima di cambiare qualsiasi cosa. Non puoi modificare i dati senza lasciare un segno. Questo processo è chiamato "invio di un'azione" in gergo Redux.
- Il codice che modifica i dati deve comportarsi come una formula matematica. Deve restituire lo stesso risultato dato lo stesso input. Il quadrato di 4 è sempre 16, non importa quante volte lo esegui.
Quando segui queste regole per creare app, accade la magia. Consente molte funzioni interessanti che altrimenti sarebbero difficili o costose da implementare. Ecco alcuni esempi. 2
2 Ho raccolto questi esempi dal post di Dan Abramov "You Might Not Need Redux" e dal suo "React Beginner Question Thread".
Annulla Ripristina
La popolare funzione di annullamento/ripristino richiede una pianificazione a livello di sistema. Poiché l'annullamento/ripetizione deve registrare e riprodurre ogni singola modifica dei dati nell'app, è necessario tenerne conto nell'architettura sin dall'inizio. Se viene fatto come ripensamento, richiederebbe la modifica di molti file, il che è una ricetta per innumerevoli bug.
Poiché Redux richiede che ogni azione sia descritta in chiaro, il supporto per annulla/ripristina è quasi gratuito. Le istruzioni su come implementare undo/redo con Redux si adattano a una semplice pagina.
Ambiente collaborativo
Se stai creando un'app simile a Google Docs in cui più utenti lavorano insieme su un'attività complessa, prendi in considerazione l'utilizzo di Redux. Probabilmente farà molto sollevamento pesi per te.
Redux rende molto facile inviare ciò che sta accadendo sulla rete. È semplice ricevere le azioni eseguite da un altro utente su un altro computer, riprodurre le modifiche e unirle a ciò che sta accadendo localmente.
Interfaccia utente ottimista
L'interfaccia utente ottimista è un modo per migliorare l'esperienza utente di un'app. Fa sembrare che l'app risponda più velocemente su una rete lenta. È una strategia popolare nelle app che richiedono risposte in tempo reale, ad esempio uno sparatutto in prima persona.
Come semplice esempio, nell'app Twitter, quando fai clic con il cuore su un tweet, è necessario richiedere al server di eseguire alcuni controlli, ad esempio, se quel tweet esiste ancora. Invece di aspettare molti secondi per il risultato, l'app sceglie di imbrogliare! Presuppone che tutto sia a posto e mostra subito un cuore pieno.
Questo approccio funziona perché la maggior parte delle volte va tutto bene. Quando le cose non vanno bene, l'app ripristina i precedenti aggiornamenti dell'interfaccia utente e applica il risultato effettivo dal server, ad esempio mostra un messaggio di errore.
Redux supporta l'interfaccia utente ottimistica allo stesso modo di come fa per annullare e ripetere. Semplifica la registrazione, la riproduzione e il ripristino delle modifiche dei dati quando si riceve un risultato negativo dal server.
Persistenza e avvio dallo stato
Redux semplifica il salvataggio di ciò che sta accadendo in un'app nella memoria. In seguito, anche se il computer si riavvia, l'app può caricare tutti i dati e continuare esattamente dallo stesso punto, come se non fosse mai stata interrotta.
Se crei un gioco con Redux, ti serviranno solo un paio di righe di codice in più per salvare/caricare i progressi del gioco, senza modificare il resto del codice.
Sistemi davvero estensibili
Con Redux, devi "inviare" un'azione per aggiornare i dati in un'app. Questa restrizione consente di agganciarsi a quasi ogni aspetto di ciò che sta accadendo in un'app.
Puoi creare app davvero estensibili in cui ogni funzione può essere personalizzata dall'utente. Ad esempio, dai un'occhiata a Hyper, un'app terminale creata con Redux. L'estensione "iperpotenza" aggiunge spruzzi al cursore e scuote la finestra. Ti piace questa modalità "wow"? (Forse non molto utile ma abbastanza per impressionare gli utenti)
Debug dei viaggi nel tempo
Che ne dici di viaggiare nel tempo durante il debug di un'app? Esegui l'app, riavvolgi o avanti alcune volte per trovare il punto esatto in cui si verifica il bug, correggi il bug e riproduci di nuovo per confermare.
Redux realizza questo sogno degli sviluppatori. Redux DevTools ti consente di manipolare l'avanzamento di un'app in esecuzione come un video di YouTube, trascinando un cursore!
Come funziona? Ricordi le tre regole rigide che Redux applica? Questa è la salsa segreta della magia.
Segnalazioni automatiche di bug
Immagina questo: un utente trova qualcosa che non va nella tua app e vuole segnalare il bug. Ricorda scrupolosamente e descrive ciò che ha fatto. Uno sviluppatore prova quindi a seguire i passaggi manualmente per vedere se il bug si verifica di nuovo. La segnalazione di bug potrebbe essere vaga o imprecisa. Lo sviluppatore ha difficoltà a trovare dove si trova il bug.
Ora, che ne dici di questo. L'utente fa clic sul pulsante "Segnala bug". Il sistema invia automaticamente ciò che ha fatto allo sviluppatore. Lo sviluppatore fa clic sul pulsante "Riproduci bug" e osserva come si verifica esattamente quel bug. Il bug è stato schiacciato sul posto, tutti sono felici!
Questo è esattamente ciò che accadrebbe se utilizzi Redux Bug Reporter. Come funziona? Le restrizioni Redux fanno miracoli.
Svantaggi di Redux
Le tre regole principali che Redux applica sono un'arma a doppio taglio. Consentono potenti funzionalità, ma allo stesso tempo causano inevitabili svantaggi.
Ripida curva di apprendimento
Redux ha una curva di apprendimento relativamente ripida. Ci vuole tempo per capire, ricordare e abituarsi ai suoi schemi. Non è consigliabile imparare Redux e React contemporaneamente se sono entrambi nuovi per te.
Codice “caldaia”.
In molti casi, usare Redux significa scrivere più codice. Spesso è necessario toccare più file per far funzionare una semplice funzione. Le persone si sono lamentate del codice "boilerplate" che avrebbero dovuto scrivere con Redux.
Lo so, questo suona contraddittorio. Non ho detto che Redux consente di implementare funzionalità con un codice minimo ? Questo è un po' come usare una lavastoviglie. In primo luogo, dovresti passare il tempo a disporre con cura i piatti in file. Solo allora vedrai i vantaggi della lavastoviglie: risparmiare tempo per pulire effettivamente le stoviglie, igienizzare le stoviglie ecc. Devi decidere se ne vale la pena!
Penalità di prestazione
Redux potrebbe anche avere un impatto sulle prestazioni a causa delle restrizioni che impone. Aggiunge un piccolo sovraccarico ogni volta che i dati cambiano. Nella maggior parte dei casi, non è un grosso problema e il rallentamento non è evidente. Tuttavia, quando c'è una grande quantità di dati nel negozio e quando i dati cambiano frequentemente (ad esempio quando l'utente digita rapidamente su un dispositivo mobile), l'interfaccia utente potrebbe diventare lenta di conseguenza.
Bonus: Redux non è solo per reagire
Un malinteso comune è che Redux sia solo per React. Sembra che Redux non possa fare nulla senza React. In effetti, Redux integra React in alcuni modi importanti, come abbiamo discusso in precedenza. È il caso d'uso più comune.
Tuttavia, in effetti, Redux può funzionare con qualsiasi framework front-end, come Angular, Ember.js o persino jQuery, o persino JavaScript vanilla. Prova a googlare, troverai questo, questo, questo o anche questo. Le idee generali di Redux si applicano ovunque!
Finché usi Redux con saggezza, puoi ottenere i suoi vantaggi in molte situazioni, non solo in un'app React.
Conclusione
Come qualsiasi strumento, Redux offre un compromesso. Abilita funzionalità potenti ma presenta anche inevitabili inconvenienti. Il compito di un team di sviluppo è valutare se ne vale la pena e prendere una decisione consapevole.
Come designer, se comprendiamo i vantaggi e gli svantaggi di Redux, saremo in grado di contribuire a questo processo decisionale dal punto di vista del design. Ad esempio, potremmo forse progettare l'interfaccia utente per mitigare il potenziale impatto sulle prestazioni? Forse potremmo sostenere l'inclusione di funzionalità di annullamento/ripristino per rimuovere un carico di finestre di dialogo di conferma? Forse potremmo suggerire un'interfaccia utente ottimista poiché migliora l'esperienza dell'utente con un costo relativamente basso?
Comprendere i vantaggi e i limiti di una tecnologia e progettare di conseguenza. Penso che questo sia ciò che Steve Jobs intendeva con "il design è come funziona".