Нарушение инварианта: Dispatch.dispatch(...): Невозможно отправить в середине отправки
Я использую ALT для своего проекта ReactJS. Я получаю сообщение об ошибке невозможности отправки, если вызов ajax еще не выполнен, и я переключаюсь на другую страницу.
В основном, так настроен мой проект. У меня есть действие, магазин и компонент. Я запрашиваю на сервере на componentDidMount
жизненный цикл.
Действие:
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)
хранить
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')
Составная часть
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>
}
}
}
3 ответа
componentDidMount() {
EventStore.listen(this._onChange.bind(this));
EventActions.findNear({page: this.state.page, per: this.state.per});
}
Это будет моя догадка. Вы связываете onChange, который будет вызывать setState в _onChange, а также будет запущено действие из findNear (из-за отправки). Так что может быть момент, когда оба обновляются одновременно.
Прежде всего, findNear, по моему мнению, должен быть первым в componentDidMount.
А также попробуйте разделить его на 2 разных представления (тупой и логический, где первый будет отображать только данные, а другой, например, будет выполнять выборку). Также хорошей идеей является также использование AltContainer, чтобы фактически избежать действия _onChange, которое довольно бесполезно из-за того, что AltContainer имеет подобные вещи "внутри".
constructor() {
this.events = {};
this.rsvp = {};
this.bindListeners({
findNear: EventActions.findNear
});
}
findNear(events) {
this.events = events
}
Также я бы рефакторинг этого в
constructor() {
this.events = {};
this.rsvp = {};
}
onFindNear(events) {
this.events = events
}
У Alt есть довольно приятные вещи, такие как автоопределители, которые будут искать имя действия + on, поэтому если у вас есть действие с именем findNear, оно будет искать onFindNear.
Я не могу понять, почему вы получите эту ошибку, потому что код, который вы предоставили, показывает только одно действие.
Однако я предполагаю, что ваш компонент был смонтирован в результате какого-либо другого действия в вашей системе. Если это так, то ошибка будет вызвана действием, инициируемым в componentDidMount
,
Может быть, попробуйте использовать Alt's action.defer
:
componentDidMount() {
EventStore.listen(this._onChange.bind(this));
EventActions.findNear.defer({page: this.state.page, per: this.state.per});
}
Я полагаю, это потому, что вы вызываете действие, и отправка этого действия происходит только после завершения запроса.
Я бы предложил разделить действие findNear на три действия: findNear, findNearSuccess и findNearFail.
Когда компонент вызывает findNear, он должен отправлять немедленно, даже до отправки запроса, чтобы соответствующие компоненты обновлялись в соответствии с выполняемым запросом (например, отображать знак загрузки, если хотите)
и внутри того же действия он должен вызвать другое действие findNearSuccess.
Статья " Извлечение данных" должна быть особенно полезной.