В примере с асинхронным режимом Flux / Alt Basic выбрасывается сообщение Не удается отправить в середине отправки

Я изо всех сил пытаюсь обойти ошибку Cannot dispatch in the middle of a dispatch, которую мне бросает Flux, на простом примере.

На мой взгляд, у меня есть кнопка, которая запускает socialLogin(token) действие на моем AuthActions. С Alt на моем действии я generateActions('login');

Мой метод socialLogin выполняет запрос Async API, который возвращает обещание (Api - простой класс, использующий библиотеку запроса):

// AuthActions
socialLogin(type, access_token) {
    Api.request('get', 'auth/social', { type, access_token })
       .then((payload) => {
           if (payload.code !== 'OK') {
               // Do something...
           } else {
               this.actions.login(payload.data.token);
           }
       })
       .catch((response) => {
           console.log('ERROR', response);
           // Do something....
       });
    this.dispatch();
}

В настоящее время метод Store onLogin ничего не делает.

Однако запуск этого метода вызывает / обнаруживает ошибку Uncaught (in promise) Error: Invariant Violation: Dispatch.dispatch(...): Cannot dispatch in the middle of a dispatch.(…).

Я не могу понять, почему, прочитав много вопросов / статей, this.dispatch() не должен "разрешить" текущее отправляемое действие?

Как мне запустить здесь какое-то другое действие или даже запустить несколько действий (войти в систему, использовать другое внешнее действие и т. Д.).

Спасибо!


person Alias    schedule 18.11.2015    source источник


Ответы (3)


Я думаю, что в вашем примере вы можете просто полностью опустить строку this.dispatch();, и она должна. Функция создания действия socialLogin вызывается как часть самой диспетчеризации, поэтому вызывать диспетчеризацию запрещено. Если вы действительно хотите отправить действие socialLogin в начале процесса входа в систему (например, чтобы разрешить установку счетчика или чего-то еще), вы можете вернуть полезную нагрузку, которую хотите отправить. например заменить this.dispatch(); на

return { type, access_token }; 

Таким образом, магазины могут прослушивать socialLogin, если хотят отследить начало процесса.

person TomW    schedule 19.11.2015

вам нужно this.actions.myAnotherAction(), где myAnotherAction - другое действие в AuthActions в вашем случае. Смотреть

person Lohith Ram    schedule 29.11.2015

внутри действия просто верните обещание, например:

 socialLogin(type, access_token) {
  return (dispatch) => {
    dispatch({type:type, accessToken:access_token});
    return new Promise((resolve,reject)=>{
      Api.request('get', 'auth/social', { type, access_token })
      .then((payload) => {
       if (payload.code !== 'OK') {
           // Do something...
       } else {
           this.actions.login(payload.data.token);
       }
       resolve(payload);
       })
       .catch((response) => {
       console.log('ERROR', response);
       // Do something....
       reject(response);
       });
    }
  }

}

Также иногда в представлениях контейнера / контроллера вы можете вызывать действия в результате этого действия, которое приведет к той же ошибке. В этом случае просто вызовите любое последующее действие с опцией отсрочки в отправке, например:

  myaction.actionname.defer(options);
person abhisekpaul    schedule 10.10.2016