Redux - Angular: как предотвратить действия, вызываемые дважды? - PullRequest
0 голосов
/ 14 ноября 2018

Redux Это очень классная библиотека, она мне действительно нравится, но как я могу предотвратить двойной вызов этих действий?Какие ошибки могут порождать такое поведение?Учтите, что я уже отписался о подписке на контроллер

constructor(private _store: Store<AppState>) {
    this.subscription = this._store.select('reduxObj').subscribe(function (item) {
      switch (item.type) {
        case fromAction.GETITEMS: {
          break;
        }
      }
    }.bind(this));
  }

  ngOnDestroy() {
    this.subscription.unsubscribe();
  }


  ngOnInit() {
    this._store.dispatch(new fromAction.GetListAction());
  }



    //REDUCER
    export function ReduxReducer(state: any = undefined, action: fromAction.actions) {

  switch (action.type) {
    case fromAction.GETITEMS: {
      return { ...state, type: fromAction.GETITEMS }
    }
  }


  //ACTION
  export class GetListAction implements Action {
    readonly type = GETITEMS;
    constructor() { }
  }

Ответы [ 2 ]

0 голосов
/ 14 ноября 2018

Люди, кажется, сосредоточены на тривиальных вещах.

Так что я прямо отвечу на ваш вопрос:

a select в магазине прослушивает dispatch событий в его наиболее простой реализации.

Вы дважды звоните dispatch, ваша подписка вызывается дважды.

Теперь это может измениться с эффектами и так далее, но я предполагаю, что у вас их нет.

Если он вызывается дважды, то это потому, что для вашего магазина создается значение по умолчанию В ваших редукторах подпись

(state: MyState, action: MyAction implements Action) => any

И вообще, вы это так выразились

myReducer(state: MyState = undefined, action: MyAction implements Action) { ... }

Это означает, что ваше первое значение равно undefined, и если вы вызываете dispatch, ваше второе значение будет определено.

Вот откуда приходят два звонка.

И, как примечание, вы можете оставить это в конструкторе, это ни черта не изменит.

EDIT

Чтобы игнорировать первое значение, вы можете использовать filter или skip (не все сразу, выберите одно в зависимости от того, что вы хотите):

this.subscription = this._store.select('reduxObj').pipe(
  // For an array, will ignore all empty arrays
  filter(value => value.length),
  // For undefined, will ignore all falsy values
  filter(value => !!value),
  // Ignore first value only
  skip(1),
)
0 голосов
/ 14 ноября 2018

Прежде всего вам не нужно .bind(this), чтобы функционировать наблюдатель. Во-вторых, вы можете использовать функции стрелок ES6 вместо обычных функций javascript в качестве функции обратного вызова (() => {}).

Когда дело доходит до вашего вопроса - лучший вариант взять только одно значение из Observable - это добавить take() stage в канал RxJS, например:

         this.subscription = this._store.select('reduxObj')
           .pipe(take(1))
           .subscribe((item) => {
              switch (item.type) {    
                case fromAction.GETITEMS:{                                                                                                        
                  //...                                    
                  break;
                }
              }
        }); 

Чтобы использовать его, вы должны импортировать take из 'rxjs / operator', предполагая, что вы используете библиотеку RxJS 5.5 или выше.

import { take } from 'rxjs/operators';
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...