2016-04-04 2 views
3

Ich verwende ALT für mein ReactJS-Projekt. Ich bekomme den Fehler 'Versand' nicht, wenn der Ajax-Anruf noch nicht erledigt ist und ich auf eine andere Seite umschalte.Invariant Violation: Dispatch.dispatch (...): Kann nicht in der Mitte eines Versands senden

Meistens ist so mein Projekt eingerichtet. Ich habe Aktion, Geschäft und Komponente. Ich frage auf dem Server auf dem componentDidMount Lebenszyklus.

Aktion:

import alt from '../altInstance' 

    import request from 'superagent' 
    import config from '../config' 

    import Session from '../services/Session' 

    class EventActions { 
    findNear(where) { 
     if (!Session.isLoggedIn()) return 
     let user = Session.currentUser(); 

     request 
     .get(config.api.baseURL + config.api.eventPath) 
     .query(where) 
     .set('Authorization', 'Token token=' + user.auth_token) 
     .end((err, res) => { 
      if (res.body.success) { 
      this.dispatch(res.body.data.events) 
      } 
     }); 
    } 
    } 

    export default alt.createActions(EventActions) 

Shop

import alt from '../altInstance' 
    import EventActions from '../actions/EventActions' 

    class EventStore { 
    constructor() { 
     this.events = {}; 
     this.rsvp = {}; 

     this.bindListeners({ 
     findNear: EventActions.findNear 
     }); 
    } 

    findNear(events) { 
     this.events = events 
    } 

    } 

    export default alt.createStore(EventStore, 'EventStore') 

Komponente

import React from 'react'; 

    import EventActions from '../../actions/EventActions'; 
    import EventStore from '../../stores/EventStore'; 
    import EventTable from './tables/EventTable' 

    export default class EventsPage extends React.Component { 
    constructor(props) { 
     super(props); 

     this.state = { 
     loading: true, 
     events: [], 
     page: 1, 
     per: 50 
     } 
    } 

    componentDidMount() { 
     EventStore.listen(this._onChange.bind(this)); 
     EventActions.findNear({page: this.state.page, per: this.state.per}); 
    } 

    componentWillUnmount() { 
     EventStore.unlisten(this._onChange); 
    } 

    _onChange(state) { 
     if (state.events) { 
     this.state.loading = false; 
     this.setState(state); 
     } 
    } 

    render() { 
     if (this.state.loading) { 
     return <div className="progress"> 
      <div className="indeterminate"></div> 
     </div> 
     } else { 
     return <div className="row"> 
      <div className="col m12"> 
       <h3 className="section-title">Events</h3> 
       <UserEventTable events={this.state.events}/> 
      </div>  
     </div> 
     } 
    } 
    } 

Antwort

1
componentDidMount() { 
     EventStore.listen(this._onChange.bind(this)); 
     EventActions.findNear({page: this.state.page, per: this.state.per}); 
    } 

Das wäre mein Wille raten. Sie binden onChange, was setState in _onChange auslöst, und auch eine Aktion wird von findNear ausgelöst (wegen des Versands). Es könnte also einen Moment geben, in dem beide gleichzeitig aktualisiert werden.

Zuerst, findNear sollte meiner Meinung nach zuerst in componentDidMount sein.

Und auch versuchen, es in 2 verschiedenen Ansichten zu trennen (dumm und logisch eins, wo zuerst würde nur Daten anzeigen, während die andere würde zum Beispiel holen). Es ist auch eine gute Idee, AltContainer zu verwenden, um eine _onChange-Aktion zu vermeiden, die ziemlich nutzlos ist, weil AltContainer ähnliche Sachen "drinnen" hat.

constructor() { 
    this.events = {}; 
    this.rsvp = {}; 
    this.bindListeners({ 
    findNear: EventActions.findNear 
    }); 
} 

findNear(events) { 
    this.events = events 
} 

Auch würde ich diese in

constructor() { 
    this.events = {}; 
    this.rsvp = {}; 
} 

onFindNear(events) { 
    this.events = events 
} 

Alt Refactoring hat recht nette Sachen wie Auto-Resolvern, die für die Aktionsnamen aussehen + auf, also wenn Sie Aktion namens findNear, wäre es suchen für onFindNear.

+0

Ich bin mir nicht sicher, was Sie mit "trennen Sie es in 2 verschiedenen Ansichten". Und übrigens, das Refindizieren von onFindNear hat nicht funktioniert. Es wird nicht angerufen. Ich folge nur den Anweisungen hier: https://github.com/goatslacker/alt – RodM

0

Ich kann nicht ganz nachvollziehen, warum Sie diesen Fehler erhalten, weil der von Ihnen bereitgestellte Code nur eine einzige Aktion anzeigt.

Meine Vermutung wäre jedoch, dass Ihre Komponente als Ergebnis einer anderen Aktion in Ihrem System eingehangen wurde. Wenn dies der Fall ist, würde der Fehler durch die ausgelöste Aktion in componentDidMount verursacht werden.

Vielleicht versuchen Alts mit action.defer:

componentDidMount() { 
    EventStore.listen(this._onChange.bind(this)); 
    EventActions.findNear.defer({page: this.state.page, per: this.state.per}); 
} 
0

Ich glaube, es ist, weil Sie eine Aktion anrufen, und der Versand für diese Aktion tritt nur dann, wenn nach der Anfrage abgeschlossen ist.

Ich würde vorschlagen, die Aktion findNear in drei Aktionen aufteilen, findNear, findNearSuccess und findNearFail.

Wenn die Komponente findNear aufruft, sollte sie sofort versandt werden, bevor sie die Anfrage einreicht, so dass die relevanten Komponenten aktualisiert werden, dass eine Anfrage läuft (z.Zeigen Sie ein Ladezeichen, wenn Sie möchten)

und innerhalb der gleichen Aktion sollte es die andere Aktion findNearSuccess aufrufen.

Der Artikel 'Fetching Data' sollte besonders hilfreich sein.

Verwandte Themen