2016-03-09 22 views
8

Im usando Flux, reagire e ho le componenti semplici e messaggi:Reagire e Flux: "spedizione nel bel mezzo di un dispaccio" per visualizzare il messaggio di errore da una chiamata API

  • Semplice: si' è un componente semplice che chiama un'API da un'azione. L'azione esegue una richiesta di posta elettronica e invia il risultato in jqXHR.done(). Semplice avere un ascoltatore di modifiche per attendere l'invio del risultato. Se il risultato è nullo, mi piacerebbe mostrare un errore usando il mio componente Messaggi, quindi chiamo il mio MessagesAction.addError('My result is null').
  • Messaggi: un componente che mostra errori per l'applicazione. Questo componente ha un listener di modifiche in attesa di nuovi messaggi da visualizzare. È inserito nell'intestazione della mia domanda.

Il problema si verifica quando si riceve il risultato nullo e si chiama immediatamente lo MessagesAction.addError all'interno del componente Semplice. In effetti, so che questo può causare l'errore "Invio nel mezzo di una spedizione", ma non so come refactoring questo codice per mostrare il messaggio di errore utilizzando Flux.

Disclaimer 1: Non riesco a utilizzare la funzione setTimeout per risolvere questo problema. Questa non è la soluzione giusta.

Disclaimer 2: il componente Simple rappresenta qualsiasi altro componente dell'app che mostrerà un messaggio anche utilizzando il componente Messaggi.

codice semplice:

findUser: function (value) { 
    UserAction.find(value); 
}, 

componentDidMount: function() { 
    UserStore.addChangeListener(this.updateUser); 
}, 

updateUser: function(){ 
    var user = UserStore.getUser(); 
    if (user == null){ 
    MessagesAction.addError('My result is null!'); //here occur the error! 
    } else { 
    //set my user with setState 
    } 
}, 
codice

Messaggi:

componentDidMount: function() { 
    MessagesStore.addChangeListener(this.addMessage); 
}, 

addMessage: function() { 
    this.setState({ 
     messages: MensagensStore.getMessages() 
    }); 
}, 

Grazie!

risposta

4

Beh, il problema è che (almeno in Dispatcher implementazione di Facebook) non si deve attivare qualsiasi azione all'interno dei callback negozio, che porterebbe ad indesiderato/comportamento imprevedibile, come dispendio infinito o cambiamenti di stato incoerenti (ad es. condizioni di gara). Ciò è dovuto alla natura di un singolo dispatcher di trasmissione.

La soluzione più pulita IMHO (senza odore waitFor()) introduce uno stato interno nel componente di attivazione. Utilizzando lo stato si attiva l'azione del messaggio nel prossimo ciclo di aggiornamento. In questo modo, non hai il problema di invii non finiti.

// your component's implementation 

getInitialState : function(){ 
    return { user : undefined }; 
} 


componentWillMount: function() { 
    UserStore.addChangeListener(this.updateUser); 
}, 

componentWillUnmount: function() { 
    UserStore.removeChangeListener(this.updateUser); 
}, 


componentDidUpdate : function(){ 
    if(this.state.user == null){ 
    MessagesAction.addError('My result is null!'); // no error anymore! 
    } 
}, 

updateUser: function(){ 
    this.setState({ user: UserStore.getUser(); }); 
}, 
4

Il contenitore di primo livello deve ascoltare le modifiche sia su UserStore che su MessageStore.

Il MessageStore deve 'waitFor' l'Userstore, ricava il suo stato (ad esempio aggiorna la proprietà dei suoi messaggi) da UserStore e quindi emette una modifica.

Qualcosa di simile a questo: Top componente livello UserContainer

findUser(value) { 
    UserAction.find(value); 
} 

componentDidMount() { 
    UserStore.addChangeListener(this.updateState); 
    MessageStore.addChangeListener(this.updateState); 
} 

updateState(){ 
    this.setState({ 
    user: UserStore.getUser(), 
    messages: MessageStore.getMessages() 
    }); 
} 

renderMessages() { 
    if(!this.state.messages) return null; 

    return (
    <Messages messages={messages} /> 
    ); 
} 

renderUser() { 
    if(!this.state.user) return null; 

    return (
    <User {...this.state.user} /> 
    ); 
} 

render() { 
    return(
    <div> 
     {this.renderMessages()} 
     {this.renderUser()} 
    </div> 
); 
} 
+0

Il componente 'Simple' rappresenta qualsiasi altro componente dell'app che mostrerà un messaggio utilizzando anche il componente Messaggi. Molti componenti, in diverse situazioni, dovranno mostrare un messaggio. – Dherik

+0

In questo caso, il componente 'Messaggi' dovrebbe essere un componente intelligente e ascoltare le modifiche sull'archivio dei messaggi stesso ... tutto ciò che dovresti fare è rendere il componente dove vuoi che i messaggi mostrino e gestirà la visualizzazione di essi . Spero che questo aiuti – Mark

+0

Sì, sta già ascoltando l'archivio (MessagesStore) per i nuovi messaggi aggiunti per un altro componente da MessageAction. Ma quando lo faccio succede il problema che ho messo in relazione. – Dherik

Problemi correlati