2015-11-06 19 views
16

per quanto ho capito Redux si tratta di mantenere tutto lo stato dell'interfaccia utente in un unico negozio (per poter riprodurre facilmente determinati stati e per non avere effetti collaterali). È possibile manipolare lo stato tramite azioni di attivazione che attivano i riduttori.Come comunicare le modifiche dello stato dell'interfaccia utente tra i componenti React con Redux?

Attualmente sto scrivendo una piccola app tipo blog in cui è possibile semplicemente creare e modificare post. Ho un dialogo per la creazione di un post, circa il metodo del componente Apprender restituisce qualcosa di simile:

<div> 
    <AppBar ... /> 
    <PostFormDialog 
     addPost={actions.addPost} 
     ref="postFormDialog" /> 
    <PostList 
     posts={posts} 
     actions={actions} /> 
</div> 

La mia domanda è: se la condizione della finestra di dialogo (aperto o chiuso) essere parte dell'oggetto Stato del componente App? E dovrebbe quindi aprire e chiudere la finestra di dialogo essere attivato tramite un'azione invece di fare qualcosa di simile a quanto segue:

onTriggerCreatePostDialog(e) { 
    this.refs.postFormDialog.show(); 
} 

dove onTriggerCreatePostDialog viene attivato attraverso qualche click ascoltatore in un pulsante "Crea" o giù di lì.

Mi sembra un po 'strano farlo tramite un'azione perché introduce una sorta di "indirezione".

Tuttavia, supponendo che voglio riutilizzare la finestra di dialogo per l'azione di modifica, devo essere in grado di aprire la finestra di dialogo da elementi che sono più in profondità nella struttura dei componenti, ad esempio, da un componente Post che è un figlio del PostList componente. Quello che ho potuto fare è passare la funzione onTriggerCreatePostDialog verso il basso della gerarchia tramite la proprietà props, ma che sembra ingombrante per me ...

Così int la fine è è anche di comunicare tra i componenti che non sono in un genitore-figlio diretto relazione. Ci sono altre opzioni? Dovrei in qualche modo utilizzare un bus evento globale? Al momento sono abbastanza incerto.

risposta

2

Lo stato per la finestra di dialogo deve trovarsi nell'archivio di ridondanza, attivato dalle azioni. se debba essere eseguito il rendering dovrebbe essere determinato controllando tale stato nel redux store.

App.render() dovrebbe essere qualcosa di simile:

render() { 
    const { showDialog } = this.props; 

    return (
    <div> 
     <AppBar ... /> 
     { showDialog ? <PostFormDialog ... /> : false } 
     <PostList ... /> 
    </div> 
); 
} 

dove mapStateToProps sarebbe qualcosa di simile state => {{ showDialog: state.showDialog }}

in termini di fornitura creatore azione, passando verso il basso l'albero oggetti di scena è probabilmente il modo corretto di fare a meno che tu non abbia qualche buona posizione dove ha senso avere un altro componente intelligente.

+0

Si supponga che la finestra di dialogo non sia modale. Inizialmente non è mostrato e il suo stato è gestito come tu proponi. Clicco su un pulsante, 'showDialog' diventa veritiero e viene mostrata questa finestra di dialogo. Ora, se dovessi fare clic in un punto diverso dalla finestra di dialogo, viene chiuso nuovamente, ma 'showDialog' non viene modificato di conseguenza, a meno che non gestisca esplicitamente tale caso in' PostFormDialog'. Questo è solo un esempio in cui la gestione dello stato del dialogo diventa ingombrante, secondo me. Lo faresti comunque? –

+0

Riguardo al componente intelligente: sarebbe forse ragionevole introdurre un altro componente intelligente per gestire lo stato della finestra di dialogo modale, ad esempio? Supponendo che la finestra di dialogo possa essere utilizzata per creare un nuovo post E modificare quelli esistenti. Inoltre devi gestire cose come "cancellare" la finestra di dialogo dopo la creazione/modifica riuscita e così via ... –

+0

questo approccio funzionerà, ma interromperà anche qualsiasi animazione di comparsa/scomparsa della finestra di dialogo, vero? Poiché il componente principale è stato nuovamente sottoposto a rendering, la finestra di dialogo verrà rimossa immediatamente dallo schermo. Mi chiedo quale sia la soluzione migliore per questo? –

7

Mi sembra che tu sia sulla strada giusta. I documenti possono essere un po 'complicati all'inizio, ma posso dirvi in ​​che modo il mio team e io stiamo usando l'implementazione.

Per rispondere alla prima domanda; se lo stato è specifico per un componente, manteniamo quello stato con il componente. Un esempio di questo sarebbe un pannello che registra le pagine localmente --- nient'altro deve essere consapevole di quel comportamento. Quindi in questo caso non avremmo innescato un'azione di ridondanza quando la pagina è cambiata, che sarebbe stata gestita internamente all'interno della struttura del componente usando i riferimenti.

Il nostro stato di redux è costituito principalmente da dati raccolti tramite richieste xhr o da uno stato condiviso. Un esempio di stato condiviso gestirà un intervallo di tempo tra più componenti che utilizzano tale intervallo per visualizzare i dati.In questo caso avremmo innescato un'azione di ridondanza; aggiorna lo stato della data con qualsiasi cosa sia stata modificata (mentre aggiorna anche altri elementi dello stato tramite xhr) e poi in definitiva torna ai componenti e rielabora.

Con ciò detto, le azioni di attivazione tramite refs sono totalmente accettabili, si tratta solo del caso d'uso specifico.

Per rispondere alla seconda domanda; redux consiglia di utilizzare il concetto di componente Smart & Dumb. Quindi hai ragione a voler passare una funzione nell'albero per i componenti stupidi da utilizzare.

Utilizziamo mapDispatchToProps nella nostra installazione connect. Quindi in pratica si passa una funzione che restituisce un oggetto di funzione "dispatcher". Sarai in grado di accedere a tali funzioni direttamente nel this.props del componente smart.

Esempio di mapDispatchToProps

function mapDispatchToProps(dispatch) { 
    return { 
    myAction:() => dispatch(actions.myAction()), 
    }; 
} 

Così che funziona del 99% del tempo, ma ho incontrato alcuni casi angolo in cui operiamo utilizzare un bus evento globale, quindi non abbiate paura di utilizzare sia mentre si tenta di attenersi il più possibile al metodo componente Smart/Dumb.

Come nota a margine, è consigliabile utilizzare reselect per mappare lo stato di ridondanza al componente intelligente. È inoltre possibile trovare altre grandi risorse redux here (ci sono diverse cose elencate che usiamo).

+1

Cosa dire dell'attivazione delle azioni di Redux per i componenti di pari livello? Supponiamo che tu voglia una azione di Redux in fratello A che aggiorni il negozio per essere riconosciuto e attiva gli oggetti di scena a cui accedere nella connessione di B di fratello. Vorresti semplicemente connettere il componente genitore che ha figli A e B come figli? Grazie! –

Problemi correlati