2016-06-29 10 views
7

Czy ktoś może dać mi wskazówek, w jaki sposób wykonać następujące czynności z reagują-Redux:Jak zareagować na zmianę stanu w reduxie i wysłać inną akcję?

Składnik A wywołuje akcję, która aktualizuje stan (asynchronicznej)

Składnik B (nie jest to składnik dzieckiem) musi być w stanie wykryć, kiedy stan zmienia się i wysyła inną akcję.

Mój problem polega na tym, że próbuję wysłać akcję 2 do komponentu B, stan jest nadal w stanie początkowym i nie jest aktualizowany.

ja też próbowałem wysyłki Działanie 2 w componentWillUpdate jednak, że tworzy nieskończoną pętlę ponieważ druga akcja aktualizuje również stan (a także asynchronicznie)

Jak to wygląda mniej więcej:

//----- 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

Komponent B powinien po prostu uwzględnić czas między załadowaniem początkowym a ładunkiem. Może pokazać spinner lub nic (puste div). Nawet jeśli reduktor 'loadEvents' jest zsynchronizowany, nie ma gwarancji, że zostanie on wysłany jako pierwszy. React sam decyduje, kiedy wywołuje różne funkcje, takie jak 'shouldComponentUpdate', a nawet konstruktorzy komponentów. – DDS

Odpowiedz

2

nie patrząc na kodzie Redux, powiedziałbym komponent B jest coraz pustych danych w konstruktorze, ponieważ jest to instancja w tym samym czasie Składnik a, iw tym momencie wniosek asynchroniczny zainicjowany przez komponentu a Konstruktor jest nadal w toku.

Twój Redux powinien uruchomić akcję zawierającą odebrane dane po zakończeniu żądania asynchronicznego. Twój reduktor umieszcza te dane w stanie, co z kolei zmienia rekwizyty połączonych komponentów i zmusza je do ponownego wydania.

Należy wysyłać getEventUsers tylko wtedy, gdy istnieje domena props.eventState.eventId i uległa zmianie.

+0

To ma sens, dzięki! W jaki sposób sprawdzisz, czy istnieje domena props.eventState.eventId? Czy powinienem po prostu porównać nextProps do this.props w componentWillUpdate? – mvovchak

+1

Problem z porównywaniem this.props z nextProps polega na tym, że jeśli eventEntervent użytkownika jest zawarty w parametrze eventState, po załadowaniu użytkowników otrzymasz nowe odniesienie do eventState, więc będą one różne, nawet jeśli zdarzenie będzie takie samo, powodując eventUsers znów zostać przyniesionym. Porównywanie identyfikatora zapewnia, że ​​naprawdę patrzysz na inne wydarzenie. Może to stanowić problem, jeśli chcesz przeładować dane dla tego samego zdarzenia w pewnym momencie. Sugerowałbym znormalizowanie twojego stanu: zachowaj wszystkich załadowanych użytkowników w osobnym obiekcie odwzorowując ich identyfikatory na dane użytkownika, a następnie odwołaj się do nich po identyfikatorze w obiektach zdarzeń. –

Powiązane problemy