Как изменить объект состояния, когда одно из полей является массивом? - PullRequest
0 голосов
/ 30 сентября 2018

У меня есть дерево состояний этой формы:

    const initialState = {
    total: 0,
    discount: 0,
    typeDiscount: 0,
    products: data
};

В каком поле продуктов находится массив, а массив выглядит так:

[{
   "id":9090,
   "name":"Item1",
   "price":200,
   "discount":10,
   "type":"fiction",
   "quantity": 1,
   "img_url":"https://store.lexisnexis.com.au/__data/media/catalog/thumb//placeholder.jpg"
},
{
   "id":9091,
   "name":"Item2",
   "price":250,
   "discount":15,
   "type":"literature",
   "quantity": 1,
   "img_url":"https://store.lexisnexis.com.au/__data/media/catalog/thumb//placeholder.jpg"
}]

Теперь я пытаюсьизмените количество в этом массиве, я новичок в Redux, поэтому, пожалуйста, сообщите мне, как это сделать?

А вот мой редуктор:

case types.ADD_ITEM_CART:
        let product_add = state.products
        for (let i = 0; i < product_add.length; i++) {
            if (product_add[i].id === action.id) {
                product_add[i].quantity = product_add[i].quantity + 1
                break
            }
        }
        return dotProp.set(state, `products`, product_add);

Ответы [ 3 ]

0 голосов
/ 30 сентября 2018

С помощью операторов распространения ... и array.map() вы можете создать новый массив продуктов, в котором все продукты, не соответствующие идентификатору, будут сохранять одну и ту же ссылку на объект, пока вы создаете новый объект продукта для интересующего вас продукта:

case types.ADD_ITEM_CART:
    const updatedProducts = state.products.map(product => {
       if (product.id === action.id) {
            const newQuantity = product.quantity + 1;
            return { ...product, quantity: newQuantity };
        }

        return product;
    })

    return { ...state, products: updatedProducts };
}

Редактировать: Удалить можно легко реализовать с помощью метода array.filter(), который создаст новый массив, содержащий только те элементы, которые соответствуют вашей функции предиката;в этом случае все продукты, которые не соответствуют идентификатору продукта, который вы хотите удалить:

 case types.REMOVE_ITEM_CART:
    const updatedProducts = state.products.filter(product => product.id !== action.id)

    return { ...state, products: updatedProducts };
}
0 голосов
/ 30 сентября 2018

Не изменяйте свое состояние таким образом для Redux или React.Копирование объектов не создает разные объекты.Если вы изменяете свойство на новое, вы также изменяете исходное свойство.

Обычно мы используем Object.assign или расширенный синтаксис в сочетании с такими методами, как .map, .filter.Object.assign или синтаксис распространения тоже не создает совершенно разных объектов.Они создают неглубокие копии, это означает одну копию уровня.Если вы изменяете вложенное свойство для нового объекта, вы снова изменяете исходное.Итак, объедините все эти инструменты.

case types.ADD_ITEM_CART: {
    // We are mapping our related array.
    const newProducts = state.products.map( el => {
      // If id does not match, return the element without doing nothing.
      if ( el.id !== action.id ) { return el };
      // id match, increment the quantity.
      return { ...el, quantity: el.quantity + 1 };
    })
    // Lastly, return our state again without mutating it.
    return { ...state, products: newProducts };
}

Если мы хотим удалить элемент из массива, мы обычно используем для этого метод .filter.

const newProducts = state.products.filter( el => el.id !== action.id );
return { ...state, products: newProducts };
0 голосов
/ 30 сентября 2018

Вы можете использовать Array.prototype.map , перебирать элементы и обновлять элемент, соответствующий id из полезной нагрузки.

Примерно так:

const state = [{
    "id": 9090,
    "name": "Item1",
    "price": 200,
    "discount": 10,
    "type": "fiction",
    "quantity": 1,
    "img_url": "https://store.lexisnexis.com.au/__data/media/catalog/thumb//placeholder.jpg"
  },
  {
    "id": 9091,
    "name": "Item2",
    "price": 250,
    "discount": 15,
    "type": "literature",
    "quantity": 1,
    "img_url": "https://store.lexisnexis.com.au/__data/media/catalog/thumb//placeholder.jpg"
  }
];

const payload = {
  id: 9091
};

const nextState = state.map(product => {
  if (product.id !== payload.id) {
    // not our product, return as is
    return product;
  }
  return {
    ...product,
    quantity: product.quantity + 1
  }
});

console.log(nextState);
.as-console-wrapper {
  max-height: 100% !important;
}

Для удаления предметов вы можете просто использовать Array.prototype.filter :

const state = [{
    "id": 9090,
    "name": "Item1",
    "price": 200,
    "discount": 10,
    "type": "fiction",
    "quantity": 1,
    "img_url": "https://store.lexisnexis.com.au/__data/media/catalog/thumb//placeholder.jpg"
  },
  {
    "id": 9091,
    "name": "Item2",
    "price": 250,
    "discount": 15,
    "type": "literature",
    "quantity": 1,
    "img_url": "https://store.lexisnexis.com.au/__data/media/catalog/thumb//placeholder.jpg"
  }
];

const payload = {
  id: 9091
};

const nextState = state.filter(product => product.id !== payload.id);

console.log(nextState);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...