2015-05-20 20 views
5

ho una struttura componente simileReactJS concomitante SetState race condition

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

idea è che le azioni sui componenti a blocco E vengono elaborati da una funzione di componente A allo stato di A e di passate al B e C come oggetti di scena. Lo so, il modo migliore era usare Flux, pubsub-js o altri sistemi di messaggi del negozio, ma spero che qualcuno possa spiegare perché la soluzione corretta non sia efficace.

chiamata a questa funzione di componente A simalteneously da più istanze del componente E porta a correre condizioni con un solo cambiamento di stato (al posto di ogni chiamata di funzione che fornisce un cambiamento)

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

aggiornamento Funzione ecco che arriva da

import update from 'react/lib/update'; 

soluzione inappropriato che va contro ReactJS consigliato pratiche, ma funziona bene:

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

La mia domanda è:

È un bug, che più setState simalteneous invoca una condizione di competizione, o sto facendo qualcosa di sbagliato senza comprenderlo?

+2

setState è destinata ad essere asincrono, ed è dosato da React quando possibile per le prestazioni – user120242

+1

Si può Voglio anche inviare una richiamata http://stackoverflow.com/questions/25172850/reactjs-this-setstate-out-of-sync-with-this-state-myvar –

risposta

13

Probabilmente si desidera passare una funzione a setState che dovrebbe rimuovere tali condizioni di gara. Qualcosa di simile:

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

Anche se due diverse parti della vostra applicazione fa questo, allo stesso tempo, entrambe le funzioni saranno ancora essere chiamati e someProp sarà incrementato due volte.

Se si dovesse fare questo invece: this.setState({someProp: this.state.someProp + 1}) si dovrebbe incrementare solo una volta perché this.state.someProp non viene aggiornato direttamente dopo aver chiamato setState. Ma quando si passa a una funzione su setState si ottiene come argomento l'attuale stato in sospeso, che offre la possibilità di incrementare come nel mio esempio o unire la propria mutazione con qualsiasi altra mutazione avvenuta.

+1

Credo che la funzione 'update' dovrebbe fare esattamente la stessa cosa . Per chiarire - nel mio caso accedo a diverse proprietà dell'oggetto di stato complesso sovrascrivendole. – akaprog

1

In base alla documentazione di React, come indicato nella prima risposta, è possibile passare una funzione per garantire il funzionamento dell'atomicità. Il fatto è che non si deve modificare lo stato, ma restituire il nuovo valore all'interno della funzione passata:

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

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

Problemi correlati