2015-05-20 12 views
5

I eine Komponentenstruktur habe wie dieseReactJS gleichzeitig SetState race condition

<A> 
    <B> 
     <C/> 
     <C/> 
    </B> 
    <D> 
     <E/> 
     <E/> 
    </D> 
</A> 

Idee ist, dass Aktionen auf Komponenten im Block E von einer Funktion der Komponente A in dem Zustand von A und als weitergegeben zu B verarbeitet werden, und C als Requisiten. Ich weiß, dass es besser wäre, Flux, pubsub-js oder ein anderes Store-Nachrichtensystem zu verwenden, aber hoffe, wenn jemand erklären kann, warum die richtige Lösung meines Wissens nicht funktioniert.

diese Funktion der Komponente A Aufruf simalteneously von mehreren Instanzen der Komponente E führt mit nur einer Änderung im Zustand Zustand zu laufen (statt jede Anruffunktion eine Änderung bereitstellt)

updateState(value,index){ 
    this.setState(update(this.state, { 
     a: { 
      [index]: { 
      b: { 
      $set: value 
      } 
      } 
     } 
    }) 
); 
} 

Funktion Update hier kommt von

import update from 'react/lib/update'; 

Bad-Lösung, die gegen ReactJS reccomended Praktiken geht, funktioniert aber gut:

updateState(value,index){ 
    this.state.a[index].b=value; 
    this.forceUpdate(); 
); 
} 

Meine Frage ist:

Ist es ein Fehler, dass mehrere simaltene setState eine Race-Bedingung aufruft, oder mache ich etwas falsch, ohne es zu verstehen?

+2

setState gemeint ist asynchron zu sein, und wird durch Reagieren chargiert, wann immer möglich, die Leistung – user120242

+1

Sie können will auch einen Rückruf http://stackoverflow.com/questions/25172850/reactjs-this-setstate-out-of-sync-with-this-state-myvar –

Antwort

13

Sie möchten wahrscheinlich eine Funktion an setState übergeben, die solche Race-Bedingungen entfernen sollte. Etwas wie:

this.setState(currentState => { 
    currentState.someProp++; 
    return currentState; 
}); 

Selbst wenn zwei verschiedene Teile der Anwendung tut dies zugleich, werden beide Funktionen noch aufgerufen werden und someProp wird zweimal erhöht werden.

Wenn Sie dies stattdessen tun würden: this.setState({someProp: this.state.someProp + 1}) würde es nur einmal inkrementiert werden, weil this.state.someProp nicht direkt nach dem Aufruf setState aktualisiert wird. Aber wenn Sie eine Funktion an setState übergeben, erhalten Sie den aktuellen ausstehenden Status als ein Argument, das Ihnen die Option gibt, entweder wie in meinem Beispiel nur zu erhöhen oder Ihre Mutation mit einer anderen Mutation zusammenzuführen, die stattgefunden hat.

+1

ich glaube, senden, dass 'update' Funktion das gleiche genau tun soll . Zur Klarstellung - in meinem Fall greife ich auf verschiedene Eigenschaften komplexer Zustandsobjekte zu, die sie überschreiben. – akaprog

1

Laut React-Dokumentation können Sie, wie in der ersten Antwort erwähnt, eine Funktion übergeben, um die Operation der Atomarität sicherzustellen. Die Sache ist, dass Sie nicht den Zustand ändern sollte, aber den neuen Wert innerhalb der übergebenen Funktion zurück:

setState(function(previousState, currentProps) { 
    return {myInteger: previousState.myInteger + 1}; 
}); 

https://facebook.github.io/react/docs/component-api.html