2016-06-29 5 views
7

Kann mir jemand geben Hinweise, wie man mit reagieren-redux Folgendes zu tun:Wie man auf Zustandänderung in redux reagiert und eine andere Aktion versendet?

Komponente A löst eine Aktion, die den Zustand (async)

(Komponente kein Kind von A)

Komponente B aktualisiert muss in der Lage sein, zu erkennen, wenn sich der Status ändert, und eine andere Aktion absetzen.

Mein Problem ist, wenn ich versuche, Aktion 2 in Komponente B zu versenden, der Zustand ist immer noch im Ausgangszustand und es wird nicht aktualisiert.

Ich habe auch versucht Aktion Dispatching 2 in componentWillUpdate jedoch, dass schafft eine Endlosschleife, weil die zweite Aktion aktualisiert auch den Zustand (und auch asynchron)

Dies ist, wie es aussieht, mehr oder weniger:

//----- Component A 
class ComponentA extends React.Component { 
    constructor(props) { 
    super(props); 
    this.props.dispatch(loadEvents()); // loadEvents is async and will update state.eventsState 
    } 
} 

const mapStateToProps = function (state) { 
    return { 
    eventsState: state.eventsState, 
    }; 
}; 

export default connect(mapStateToProps)(ComponentA); 


//----- Component B 
class ComponentA extends React.Component { 
    constructor(props) { 
    super(props); 
    props.dispatch(getEventUsers(props.eventsState.eventId)); // the eventsState is in initial state here (empty)...where do I call getEventUsers? 
    } 

    componentWillUpdate(nextProps) { 
    nextProps.dispatch(getEventUsers(props.eventsState.eventId)) // Creates an infinite loop, getEventUsers also updates state 
    } 
} 

const mapStateToProps = function (state) { 
    return { 
    eventsState: state.eventsState, 
    }; 
}; 

export default connect(mapStateToProps)(ComponentA); 
+0

Komponente B sollte nur die Zeit berücksichtigen, die zwischen dem Start der Last und der Last vergeht. Es könnte ein Spinner oder nichts (leeres div) zeigen. Selbst wenn Ihr "loadEvents" Reducer synchron ist, gibt es keine Garantie, dass er zuerst gesendet wird. Reaction alone entscheidet, wenn es verschiedene Funktionen wie 'sollComponentUpdate' aufruft und sogar Ihre Komponentenkonstruktoren. – DDS

Antwort

2

Ohne an Ihrem Redux Code zu suchen, würde ich Ihre Komponente B leer Daten im Konstruktor sagen wird immer, weil es etwa zur gleichen Zeit eine Komponente A, und an diesem Punkt der Asynchron-Anfrage initiiert von Komponente A instanziiert ist Konstruktor ist noch in Bearbeitung.

Ihr Redux sollte eine Aktion auslösen, die die empfangenen Daten enthält, wenn die Async-Anforderung abgeschlossen ist. Ihr Reducer versetzt diese Daten dann in den Zustand, der wiederum die Requisiten Ihrer verbundenen Komponenten verändert und sie zwingt, sie neu zu rendern.

Sie sollten getEventUsers nur dann senden, wenn props.eventState.eventId existiert und geändert wurde.

+0

Das macht Sinn, danke! Wie würden Sie prüfen, ob requiss.eventState.eventId existiert? Soll ich nextProps nur mit this.props in componentWillUpdate vergleichen? – mvovchak

+1

Das Problem beim Vergleich von this.props mit nextProps besteht darin, dass wenn Ihre eventUsers in Ihrem eventState enthalten sind, beim Laden der Benutzer eine neue eventState-Referenz erhalten wird, so dass sie sich unterscheiden, obwohl das Ereignis gleich ist und eventUsers verursacht wieder abgeholt werden. Vergleicht man die ID, stellt man sicher, dass man wirklich auf ein anderes Event schaut. Dies kann ein Problem sein, wenn Sie die Daten für dasselbe Ereignis irgendwann erneut laden möchten. Ich würde vorschlagen, Ihren Status zu normalisieren: Halten Sie alle geladenen Benutzer in einem separaten Objekt, das ihre IDs den Benutzerdaten zuordnet, und verweisen Sie dann anhand der ID auf Ereignisobjekte. –