React-Redux: tutti gli stati dei componenti devono essere mantenuti in Redux Store


89

Diciamo che ho un semplice interruttore:

Quando faccio clic sul pulsante, il componente Colore cambia tra rosso e blu

Potrei ottenere questo risultato facendo qualcosa di simile.

index.js

Button: onClick={()=>{dispatch(changeColor())}}
Color: this.props.color ? blue : red

container.js

connect(mapStateToProps)(indexPage)

action_creator.js

function changeColor(){
 return {type: 'CHANGE_COLOR'}
}

riduttore.js

switch(){
case 'CHANGE_COLOR':
return {color: true}

ma questo è un sacco di codice da scrivere per qualcosa che avrei potuto ottenere in 5 secondi con jQuery, alcune classi e alcuni css ...

Quindi immagino che quello che sto chiedendo davvero sia, cosa sto facendo di sbagliato qui?


6
react-redux non è venduto come qualcosa che è più corto di jquery. Ha sicuramente bisogno di un po 'di codice per renderlo operativo.
zerkms

1
Dai un'occhiata qui: github.com/rackt/redux/issues/1287 ci sono molte buone discussioni sull'argomento.
m0meni

1
grazie @ AR7 è perfetto
l2silver

1
@ l2silver nessun problema. Fondamentalmente l'idea è che se il colore di quel componente non è importante per nessun altro, mantieni quello stato interno al componente stesso.
m0meni

2
il problema menzionato da AR7 è stato spostato: github.com/reactjs/redux/issues/1287
ptim

Risposte:


154

Redux è destinato principalmente allo "stato dell'applicazione". Cioè, tutto ciò che riguarda la logica dell'applicazione. La vista costruita sopra è un riflesso di quello stato, ma non deve utilizzare esclusivamente quel contenitore di stato per tutto ciò che fa.

Poni semplicemente queste domande: questo stato è importante per il resto dell'applicazione? Altre parti dell'applicazione si comporteranno diversamente in base a quello stato? In molti casi minori, non sarà così. Prendi un menu a discesa: il fatto che sia aperto o chiuso probabilmente non avrà alcun effetto su altre parti dell'app. Quindi, collegarlo al tuo negozio è probabilmente eccessivo. È certamente un'opzione valida, ma non ti procura alcun vantaggio. È meglio usarlo this.statee chiamarlo un giorno.

Nel tuo esempio particolare, il colore di quel pulsante è attivato per fare la differenza in altre parti dell'applicazione? Se è una sorta di attivazione / disattivazione globale per una parte importante della tua applicazione, appartiene sicuramente allo store. Ma se stai solo cambiando il colore di un pulsante quando fai clic sul pulsante, puoi lasciare lo stato del colore definito localmente. L'azione di fare clic sul pulsante potrebbe avere altri effetti che richiedono l'invio di un'azione, ma questo è separato dalla semplice domanda di quale colore dovrebbe essere.

In generale, cerca di mantenere lo stato dell'applicazione il più piccolo possibile. Non devi spingere tutto lì dentro. Fallo quando devi o ha molto senso tenere qualcosa lì. O se ti semplifica la vita quando usi Dev Tools. Ma non sovraccaricare troppo la sua importanza.


Ehi, so che non ci sarà mai una risposta definitiva a questa domanda, ma penso che la tua logica sia molto
valida

3
Ad essere onesti, non capisco affatto qual è il punto di usare quella cosa flux / redux. Qual era il problema con il modello basato sugli eventi?
jayarjo

IMO, non è la risposta perfetta. Dipende. Memorizzare lo stato dell'interfaccia utente nello stato di reazione renderà il redux store pulito ma finirà per diventare un componente non funzionale che è difficile da testare. Mentre la memorizzazione dello stato dell'interfaccia utente nello stato di reazione comporterà molti sforzi su dev, perché dobbiamo scrivere riduttori aggiuntivi. Tuttavia, ci sono molti pacchetti che possono aiutarti a rendere il tuo stato ui molto più facile da memorizzare redux, controlla redux.js.org/docs/faq/OrganizingState.html per maggiori dettagli.
Ron

19

Domande frequenti su Redux: Organizzare
questa parte del documento ufficiale di redux ha risposto bene alla tua domanda.

L'uso dello stato del componente locale va bene . In qualità di sviluppatore, è tuo compito determinare quali tipi di stato costituiscono la tua applicazione e dove dovrebbe risiedere ogni parte di stato. Trova un equilibrio che funzioni per te e seguilo.

Alcune regole pratiche comuni per determinare il tipo di dati da inserire in Redux:

  • Altre parti dell'applicazione si preoccupano di questi dati?
  • Hai bisogno di essere in grado di creare ulteriori dati derivati ​​basati su questi dati originali?
  • Gli stessi dati vengono utilizzati per guidare più componenti?
  • C'è valore per te nell'essere in grado di ripristinare questo stato a un dato punto nel tempo (cioè, il debug del viaggio nel tempo)?
  • Vuoi memorizzare nella cache i dati (ad esempio, utilizzare ciò che è nello stato se è già presente invece di richiederlo nuovamente)?

6

Allo scopo di evidenziare l'ottimo collegamento fornito da @ AR7 e poiché quel collegamento è stato spostato un po 'indietro:

Usa React per uno stato effimero che non ha importanza per l'app a livello globale e non muta in modi complessi. Ad esempio, un interruttore in un elemento dell'interfaccia utente, uno stato di input del modulo. Usa Redux per lo stato che conta a livello globale o è mutato in modi complessi. Ad esempio, utenti memorizzati nella cache o una bozza di post.

A volte potresti voler passare dallo stato Redux allo stato React (quando memorizzare qualcosa in Redux diventa scomodo) o viceversa (quando più componenti devono avere accesso a uno stato che era locale).

La regola pratica è: fai ciò che è meno imbarazzante.

Dan Abramov: https://github.com/reactjs/redux/issues/1287#issuecomment-175351978


-7

Sì, vale la pena sforzarsi di memorizzare tutto lo stato dei componenti in Redux . Se lo fai, trarrai vantaggio da molte funzionalità di Redux come il debug del viaggio nel tempo e le segnalazioni di bug riproducibili. In caso contrario, queste funzionalità potrebbero essere completamente inutilizzabili .

Ogni volta che non si memorizza una modifica dello stato di un componente in Redux, tale modifica viene completamente persa dallo stack di modifiche Redux e l'interfaccia utente dell'applicazione non sarà sincronizzata con lo store. Se questo non è importante per te, chiediti perché usare Redux? La tua applicazione sarà meno complessa senza di essa!

Per motivi di prestazioni, potresti voler ricorrere a this.setState()tutto ciò che potrebbe inviare molte azioni ripetutamente. Ad esempio: memorizzare lo stato di un campo di input in Redux ogni volta che l'utente digita una chiave può comportare prestazioni scadenti. Puoi risolvere questo problema trattandolo come una transazione: una volta che l'azione dell'utente è stata "confermata", salva lo stato finale in Redux.

Il tuo post originale menziona come il metodo Redux sia "un sacco di codice da scrivere". Sì, ma puoi usare astrazioni per modelli comuni come lo stato del componente locale.


Il debug migliorato è un obiettivo utile e una bella funzionalità di redux, ma penso che anche il rapporto segnale / rumore sia importante. Si potrebbe registrare ogni variabile in una base di codice, ma ciò aggiungerebbe molto codice extra rendendo il codice effettivo più difficile da leggere e la registrazione sarebbe difficile da cercare. Penso che lo stesso valga per l'utilizzo di redux. Avere tutti gli stati in redux può migliorare il debug, ma c'è un costo in codice aggiuntivo e astrazioni che possono rendere il codice più difficile da leggere e persino rendere più difficili alcune attività di debug. (E quando gli strumenti di redux dev si bloccano, molti dei guadagni di debug vengono persi.)
JD Sandifer,

1
Allora perché usare Redux? Se non metti tutto in Redux, perdi tutte le funzionalità, come devtools. È davvero tutto o niente. Se utilizzi setState () per un menu a discesa come nella risposta in alto a questo post, non puoi utilizzare devtools per eseguire il debug di eventuali problemi che i tuoi utenti potrebbero incontrare all'interno del menu a discesa. È peggio quando usi setState () per una sovrapposizione perché non c'è modo di viaggiare nel tempo prima e dopo la visualizzazione della sovrapposizione. Spruzzare setState () qua e là è molto soggetto a errori perché lo sviluppatore deve costantemente pensare a cosa potrebbe non funzionare.
kumar303

Come risposta più specifica, registrare ogni variabile in un codebase non è una metafora utile poiché la domanda riguarda se utilizzare this.setState()o dispatch(action...). Non è necessario utilizzarlo this.setState()ovunque, ma quando è necessario, il mio suggerimento è di utilizzare Redux invece per il 99% dei casi, ricadendo sull'1 this.setState()% in base ai problemi di prestazioni.
kumar303

La registrazione di ogni variabile mi sembra essere analoga a mettere tutto in Redux e altrettanto sconsigliabile come regola generale. Lasciare fuori alcune cose da Redux non nega le funzionalità per tutto ciò che è in Redux fintanto che lo stato è separato. Ad esempio, posso ancora eseguire il debug della mia logica di chiamata API che viene convogliata attraverso Redux anche se lo stato di una casella di selezione non lo è. L'OP ha un punto: richiede più codice in più punti per utilizzare Redux e forse ciò non è giustificato nell'esempio specifico che hanno elencato.
JD Sandifer

Potresti non essere in grado di eseguire il debug della tua logica API, in realtà. Questo è il mio punto. È davvero difficile prevedere gli scenari in cui interromperai il viaggio nel tempo, quindi è meglio mettere tutto lo stato (incluso lo stato della casella di selezione) in Redux finché non si verifica un problema di prestazioni.
kumar303
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.