NgrxStore - первый объект вставляется раз в массив - PullRequest
0 голосов
/ 29 октября 2019

Я играю с хранилищем ngrx, удаление, выборка и редактирование элементов в массиве работает очень хорошо, но проблема в том, когда я впервые вставляю объект в массив, например {id: 1, name: 'Potato', количество: 2}, два абсолютно одинаковых объекта вставляются, если я не отфильтрую его, как в приведенном ниже редукторе.

Состояние

export const initialShoppingState: ShoppingState = {
    shoppingList: [],
};

Этот работает, но, вероятно, я не должен фильтровать его, чтобы предотвратить добавление одного и того жеобъект

on(ShoppingAction.shoppingItemAdded, (state, { shoppingItem }) => {
    console.log(state);
    return ({ ...state, shoppingList: [...state.shoppingList.filter((item) => item.id !== shoppingItem.id), shoppingItem] });
}),

Этот элемент добавляет первый элемент два раза, следующие элементы - только один раз.

on(ShoppingAction.shoppingItemAdded, (state, { shoppingItem }) => {
    console.log(state);
    return ({ ...state, shoppingList: [...state.shoppingList.concat(shoppingItem)] });
}),

1 Ответ

1 голос
/ 30 октября 2019

Исходя из кода, это ожидаемое поведение, которое магазин не может решить.

Проблема в том, что вы добавляете элемент в массив. Единственное решение для этого - использовать filter, как вы сделали.

Если вы структурируете свое состояние как словарь, у вас нет этой проблемы, потому что id будет уникальным. См. Нормализующее состояние для получения дополнительной информации.

См. this для примера.

export const initialState: State = {
  cartItems: {},
};

export function reducer(state = initialState, action: CartActions) {
  switch (action.type) {
    case CartActionTypes.AddToCart:
      return {
        ...state,
        cartItems: {
          ...state.cartItems,
          [action.payload.sku]: (state.cartItems[action.payload.sku] || 0) + 1,
        },
      };

    case CartActionTypes.RemoveFromCart:
      return {
        ...state,
        cartItems: {
          ...state.cartItems,
          [action.payload.sku]: Math.max((state.cartItems[action.payload.sku] || 0) - 1, 0),
        },
      };

    case CartActionTypes.EmptyCart:
      return initialState;

    default:
      return state;
  }
}
...