2015-05-20 13 views
5

I mają strukturę składników jak toReactJS współbieżne setState wyścigu

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

Chodzi o to, że działania na składniki w bloku E są przetwarzane przez funkcję składnika A do stanu A, a nie przekazywane do B i C jako rekwizyty. Wiem, że lepszym sposobem było użycie Flux, pubsub-js lub innego systemu Store-message, ale mam nadzieję, że ktoś może wyjaśnić, dlaczego nie działa poprawne rozwiązanie.

Wywołanie tej funkcji składnika A simalteneously z wielu wystąpień komponentu E prowadzi do wyścigu stan z tylko jedną zmianą stanu (zamiast każdego wywołania funkcji przewidującej zmianę)

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

aktualizacji funkcji tutaj pochodzi z

import update from 'react/lib/update'; 

Bad rozwiązanie, które jest sprzeczne ReactJS poleciła praktyk, ale działa dobrze:

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

Moje pytanie brzmi:

Czy to błąd, że wiele simalteneous setState wywołuje stan wyścigu, czy robię coś nie tak, nie rozumiejąc go?

+2

setstate rozumie się asynchroniczny i jest dozowany przez React gdy jest to możliwe do wykonania – user120242

+1

Użytkownik może również chcesz wysłać wywołanie zwrotne http://stackoverflow.com/questions/25172850/reactjs-this-setstate-out-of-sync-with-this-state-myvar –

Odpowiedz

13

Prawdopodobnie chcesz przekazać funkcję do setState, która powinna usunąć takie warunki wyścigu. Coś jak:

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

Nawet jeśli dwie różne części aplikacji czyni to w tym samym czasie, obie funkcje będą nadal nazywa i someProp zostanie zwiększony dwukrotnie.

Jeśli zamiast tego miałbyś to zrobić: this.setState({someProp: this.state.someProp + 1}) byłoby to tylko inkrementowane tylko raz, ponieważ this.state.someProp nie jest aktualizowane bezpośrednio po wywołaniu setState. Ale przekazując funkcję do setState, otrzymujesz bieżący stan jako argument, który daje możliwość albo zwiększenia jak w moim przykładzie, albo scalenia mutacji z każdą inną mutacją, która miała miejsce.

+1

Wierzę, że funkcja 'update' powinna zrobić dokładnie to samo . Aby wyjaśnić - w moim przypadku uzyskuję dostęp do różnych właściwości złożonego obiektu stanu, zastępując je. – akaprog

1

Zgodnie z dokumentacją React, jak wspomniano w pierwszej odpowiedzi, można przekazać funkcję, aby zapewnić działanie atomowości. Chodzi o to, że nie należy zmieniać stanu, ale zwracać nową wartość wewnątrz przeszedł funkcję:

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

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

Powiązane problemy