2016-04-15 24 views
0

ich Umsetzung lerne a/Redux reagieren und eine Anwendung mit zwei Hauptstücke Zustand haben:Reagieren/Redux, mehrere Aktionen mit Redux Thunk

  1. Eine Reihe von Elementen
  2. Ein Objekt, das vom Benutzer enthält angegebene Filter für diese Elemente

ich habe drei Funktionen/Aktionen, createFilter, updateFilter und deleteFilter, die den Zustand # 2 ändern. Ich habe eine Aktion filterItems, die # 1 basierend auf dem Status von # 2 ändert. Wenn sich also # 2 ändert, muss diese Aktion ausgelöst werden.

Dies ist die Komponente, mit denen ich arbeite:

import React, { Component } from 'react' 
import { connect } from 'react-redux' 
import { bindActionCreators } from 'redux' 

import { createFilter } from '../actions/actions' 
import { updateFilter } from '../actions/actions' 
import { deleteFilter } from '../actions/actions' 
import { filterItems } from '../actions/actions' 

class ItemList extends Component { 

createFilter(input) { 
     this.props.createFilter(input) 
     this.props.filterItems() 
    } 

    updateFilter(input) { 
     this.props.updateFilter(input) 
     this.props.filterItems() 
    } 

    deleteFilter() { 
     this.props.deleteFilter() 
     this.props.filterItems() 
    } 

    ... 
    // Render method 
    ... 
} 

function mapDispatchToProps(dispatch) { 
    return bindActionCreators({ createFilter, updateFilter, deleteFilter, filterItems }, dispatch) 
} 

function mapStateToProps({ itemList }) { 
    return { itemList } 
} 

export default connect(mapStateToProps, mapDispatchToProps)(ItemList) 

Was ich habe festgestellt, dass, wenn einer der Filtermethoden gesendet wird, wird der Speicher (Stand # 2) die noch nicht von der Zeit aktualisiert filterItems() wird genannt.

Also muss ich die Filterfunktionen asynchron ausführen, und sobald der Speicher aktualisiert wird, rufen Sie filterItems.

Ich kämpfe auf, wie man das mit react-thunk macht. Wenn die erste Funktion ein AJAX-Versprechen ist, würde ich .then() verwenden:

export function updateFilterAndEvaluate(input) { 
    return (dispatch, getState) => { 
     updateFilter(input).then(dispatch(filterItems(getState().filters))) 
    } 
} 

Aber diese nur Funktionen sind, und keine .then() Methode habe. Ich versuche herauszufinden, was meine beste Vorgehensweise für diese Implementierung ist. Kann ich Redux-Aktionen in ein Versprechen einbinden? Benütze ich Thunk? Oder sollte ich ein ganz anderes Muster versuchen?

+0

Warum sollte 'updateFilter' kein Versprechen geben? –

Antwort

6

Ich habe eine Aktion filterItems, die # 1 basierend auf dem Status von # 2 ändert.

Dies ist im Allgemeinen ein Anti-Pattern. Da das Ergebnisarray aus dem Quell-Array und den derzeit aktiven Filtern berechnet werden kann, sollten Sie es nicht in diesem Zustand belassen.

Redux-Aktionen sollten im Allgemeinen wie "Ereignisse" aussehen (z. B. was passiert ist). "Filter wurde erstellt" und "Filter wurde aktualisiert" sind gute Aktionen. "Filter sie jetzt!" Sieht mehr wie ein Befehl aus, das ist normalerweise ein Zeichen, dass es keine Aktion von Anfang an sein sollte, und sollte etwas tun, was die Komponenten tun, wenn sie die zu rendernden Daten auswählen.

Stattdessen die Filterung als Teil Ihrer mapStateToProps() Funktion, wenn Sie Daten für die Komponenten vorbereiten. Wenn es teuer wird, look into using Reselect to compute derived data efficiently.

Was Ihre konkrete Frage,

Was ich gefunden habe, ist, dass, wenn einer der Filtermethoden gesendet wird, wird der Speicher (Stand # 2) nicht noch durch die Zeit filterItems aktualisiert() aufgerufen .

Dies ist falsch und weist auf ein anderes Problem in Ihrem Code hin. (Es ist schwer zu sagen, wo, weil das Beispiel unvollständig ist).In Redux ist dispatch() synchron (es sei denn, Sie haben eine Middleware, die es verzögert oder stapelt, was normalerweise nicht der Fall ist), so dass Sie nicht warten müssen, bis es fertig ist, wenn es nur mit den lokalen Daten arbeitet.

In jedem Fall ist filterItems() nicht eine sehr gute Passform für eine Aktion, und ich schlage vor, Sie in Filterung in mapStateToProps() zu untersuchen, wie ich oben schrieb.

+0

Super, danke! Das macht Sinn. Ich habe eine funktionierende Version davon, indem ich die mapStateToProps-Methode der Komponente filtere. Als Follow-up-Frage, was, wenn die Elemente die Filter passieren, werden sie von den Filtern modifiziert? Dann müssten sie in einer Aktion versandt werden, um den Laden mit ihrem neuen modifizierten Zustand zu aktualisieren? –

+1

Warum würden Filter die Artikel modifizieren? Ich verstehe den Anwendungsfall nicht. Wenn sie nur einige Dinge "formatieren", die sich temporär ändern, während der Filter angewendet wird, würde ich erwarten, dass 'mapStateToProps' kopiert, was immer es zu modifizieren braucht, und das als Props weitergibt. 'mapStateToProps' kann niemals Aktionen versenden, es sollte eine reine Funktion sein. –

+0

Ich experimentiere nur, aber der Anwendungsfall wäre, eine Kennung für den Filter in dem Element zu speichern, so dass, wenn dieses Element erneut gefiltert werden soll, Filterlogik umgangen und genehmigt werden kann. Ich kann die Filterung auch innerhalb der Komponente verschieben. –

Verwandte Themen