AlexanderBelov
@AlexanderBelov
Frontend developer

Redux использовать диспетчер для разных действий?

Разбираюсь с Redux на примере несложного приложения Shopping cart.
1.
Не могу понять, можно ли использовать 1 диспетчер для различных задач?
Например, мне нужно добавить товар в корзину и при этом изменить свойство объекта (продукта) с false ("Не в корзине") на true ("В корзине").
case ADD_PRODUCT:
                action.product.added = true; <---------- ???
			action.product.id = state.products.length + 1;
			return Object.assign({}, state, {
				products: state.products.concat(Object.assign({}, action.product))
		})
}


Или правильно будет создать для этой задачи ещё один диспетчер (при условии, что добавление / удаление товара всегда сопровождается присваиванием true / false)?

В похожих топиках, которые находил, однозначного мнения не было. Вроде, как удобно, так и делай.

2.
Правильно ли использовать для отображения блока по принципу show / hide Redux? Т.е., у меня есть span, где отображается "Добавить в корзину". Как только товар оказывается в корзине, мне нужно показать другой span "Добавлено".
Почему Redux, т.к. при переходе на другую вкладку приложения предыдущие данные сбиваются. Т.е., если я уйду со страницы с товарами, при возвращении под всеми товарами, даже под теми, которые уже в корзине, будет снова span "Добавить в корзину".
Как решить этот момент правильно?
  • Вопрос задан
  • 217 просмотров
Пригласить эксперта
Ответы на вопрос 1
dasha_programmist
@dasha_programmist
ex Software Engineer at Reddit TS/React/GraphQL/Go
диспетчер ты имеешь в виду reducer?
мне кажется логичной следующая схема:
// класс, описывающий состояние
class WishlistState {
  items: Item[];
  ids: {[id:string]:boolean};
}
// reducer
export function wishlist(state:WishlistState = null, action){
  switch(action.type){
    case ADD_PRODUCT:
      return {
        items: [...(state&&state.items || []), action.payload],
        ids: {...state.ids, ...{action.payload.id:!0}}
      };
    case FETCH_WISHLIST:
      return {
        items: action.payload,
        ids: actions.payload.reduce((acc,v)=>{acc[v.id]=!0; return acc;}, {})
      };
    default: return state;
  }
}
// сервис, через который производится вывод данных в компоненте и проверка на содержание элемента в корзине по id'шнику
class WishlistService {
  state: Observable<WishlistState>;
  items: Observable<Item[]>;
  constructor(store, api){
    this.state = store.select(s=>s.wishlist).filter(i=>!!i);
    this.items = this.state.map(i=>i.items);
  }
  fetch(){
    this.api.getWishlist().subscribe(data=>{
      this.store.dispatch({
        type: FETCH_WISHLIST,
        payload: data
      })
    })
  }
  contains(id):Observable<boolean>{
    return this.state.map(i=>!!i.ids[id]);
  }
  add(item:Item){
    this.store.dispatch({
      type: ADD_PRODUCT,
      payload: item
    })
  }
}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы