2015-11-06 14 views
16

Soweit ich Redux verstanden habe, geht es darum, den gesamten Zustand der UI in einem Speicher zu halten (um bestimmte Zustände leicht reproduzieren zu können und keine Nebenwirkungen zu haben). Sie können den Zustand über Auslöseaktionen manipulieren, die Reduzierer auslösen.Wie UI-Statusänderungen zwischen React-Komponenten mit Redux kommunizieren?

Ich schreibe gerade eine kleine blogähnliche App, wo Sie einfach Posts erstellen und bearbeiten können. Ich habe einen Dialog für einen Beitrag erstellen, etwa die render Methode der App Komponente gibt so etwas wie dieses:

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

Meine Frage ist: sollte der Zustand des Dialogs (geöffnet oder geschlossen) Teil des Staates Objekt sein der App-Komponente? Und sollte daher das Öffnen und Schließen Sie den Dialog über eine Aktion ausgelöst werden, statt nach so etwas wie das tun:

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

wo onTriggerCreatePostDialog auf einer Schaltfläche „Erstellen“ über einige Klick-Listener ausgelöst wird oder so.

Es scheint mir ein bisschen seltsam, es über eine Aktion zu tun, weil es eine Art "Indirection" einführt.

jedoch davon aus, dass ich den Dialog für die Bearbeitungsaktion wiederverwendet werden soll, muß ich in der Lage sein, den Dialog von Elementen zu öffnen, die in der Komponentenstruktur tiefer sind, beispielsweise aus einem Post Komponente, die ein Kind der PostList ist Komponente. Was ich tun könnte, ist die onTriggerCreatePostDialog Funktion unten in der Hierarchie gelangen über die props Eigenschaft, aber das scheint mir lästig, ...

So int das Ende ist auch um die Kommunikation zwischen den Komponenten, die nicht in einem direkten Eltern-Kind sind Beziehung. Gibt es andere Möglichkeiten? Soll ich irgendwie einen globalen Event-Bus nutzen? Ich bin mir momentan ziemlich unsicher.

Antwort

2

Der Status für den Dialog sollte im Redox-Speicher liegen, ausgelöst durch Aktionen. Ob es gerendert werden soll, sollte durch Überprüfung dieses Zustands im Redux-Speicher bestimmt werden.

App.render() sollte wie folgt sein:

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

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

wo mapStateToProps würde so etwas wie state => {{ showDialog: state.showDialog }}

In Bezug auf die Aktion Schöpfer liefern, vorbei an den Requisiten Baum ist wahrscheinlich der richtige Weg zu tun es sei denn, Sie haben eine gute Position, wo es sinnvoll ist, eine andere intelligente Komponente zu haben.

+0

Angenommen, der Dialog ist nicht modal. Anfangs wird es nicht angezeigt und sein Zustand wird so verwaltet, wie Sie es vorschlagen. Ich klicke auf einen Button, 'showDialog' wird truthy und dieser Dialog wird angezeigt. Nun, wenn ich irgendwo anders als der Dialog klicken würde, wird es wieder geschlossen, aber 'showDialog' wird nicht entsprechend manipuliert, es sei denn, ich behandle diesen Fall explizit in' PostFormDialog'. Das ist nur ein Beispiel, wo die Handhabung des Zustands des Dialogs meiner Meinung nach umständlich ist. Würdest du es so machen? –

+0

In Bezug auf die intelligente Komponente: Wäre es vielleicht sinnvoll, eine andere intelligente Komponente einzuführen, um beispielsweise den Status des modalen Dialogs zu verwalten? Angenommen, der Dialog kann verwendet werden, um einen neuen Beitrag zu erstellen und bestehende zu bearbeiten. Außerdem müssen Sie Dinge wie "Löschen" des Dialogs nach erfolgreicher Erstellung/Bearbeitung und so weiter behandeln ... –

+0

dieser Ansatz wird funktionieren, aber es wird auch jede Dialogdarstellung/Verschwindensanimation brechen, oder? Da die Elternkomponente neu gerendert wurde, wird der Dialog sofort vom Bildschirm entfernt. Ich frage mich, was ist die beste Umgehungsmöglichkeit dafür? –

7

Es scheint mir, dass Sie auf dem richtigen Weg sind. Die Dokumentation kann zu Beginn etwas knifflig sein, aber ich kann Ihnen sagen, wie mein Team und ich die Implementierung verwenden.

Um Ihre erste Frage zu adressieren; Wenn der Status für eine Komponente spezifisch ist, behalten wir diesen Status mit der Komponente bei. Ein Beispiel dafür wäre ein Panel, das Datensätze lokal pufft - nichts anderes muss dieses Verhalten kennen. In diesem Fall würden wir keine Reduktionsaktion auslösen, wenn sich die Seite ändert, was intern innerhalb der Komponentenstruktur mit Referenzen behandelt würde.

Unser redux-Status besteht hauptsächlich aus Daten, die über xhr-Anfragen oder aus einem gemeinsamen Status gesammelt werden. Ein Beispiel für den gemeinsamen Status wäre die Verwaltung eines Zeitbereichs zwischen mehreren Komponenten, die diesen Bereich zum Anzeigen von Daten verwenden.In diesem Fall würden wir eine Redux-Aktion auslösen; Aktualisiere den Datumsstatus mit allem, was geändert wurde (während auch einige andere Statuselemente über xhr aktualisiert werden) und dann wird das schließlich wieder an die Komponenten zurückgegeben und sie rendern erneut.

Mit dem gesagt, Auslösen von Aktionen über Refs ist völlig akzeptabel, es ist nur, was der spezifische Anwendungsfall ist.

Um Ihre zweite Frage zu adressieren; redux empfiehlt die Verwendung des Komponentenkonzepts Smart & Dumb. Du hast also recht, dass du eine Funktion im Baum nach unten geben würdest, damit die dummen Komponenten verwendet werden können.

Wir verwenden mapDispatchToProps in unserem connect Setup. Sie übergeben also grundsätzlich eine Funktion, die ein Objekt der Funktion "Dispatcher" zurückgibt. Sie können auf diese Funktionen direkt in der this.props Ihrer Smart-Komponente zugreifen.

Beispiel mapDispatchToProps

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

so dass 99% der Zeit funktioniert, aber ich habe in einigen Fällen Ecke laufen, wo wir ein globales Ereignis Bus benutzen tun, also keine Angst, beide zu verwenden, während Sie versuchen, so weit wie möglich bei der Smart/Dumb-Komponentenmethode zu bleiben.

Als eine Randnotiz würde ich empfehlen, reselect zu verwenden, um Ihren Redux-Status der Smart-Komponente zuzuordnen. Sie können auch andere große Redux-Ressourcen finden here (es gibt mehrere Dinge aufgelistet, die wir verwenden).

+1

Was ist mit Auslösen von Redux-Aktionen für Geschwisterkomponenten? Nehmen wir an, Sie möchten eine Redux-Aktion in Geschwister A, die den zu bestätigenden Speicher aktualisiert und den Zugriff auf die Requisiten in der Verbindung von Geschwister B auslöst. Würdest du nur die Verbindung in der Elternkomponente haben, die Geschwister A und B als Kinder hat? Vielen Dank! –

Verwandte Themen