Прежде всего, когда вы используете spread operator
, это только создает новую ссылку для первого уровня.Второй уровень, однако, указывает на те же ссылки.например,
let collection = [
{
someData: 1
}
]
let secondCollection = collection.map(item =>
item.someData = 2
)
console.log(collection) //[{someData: 2}]
console.log(secondCollection) //[{someData: 2}]
В этом случае вам также необходимо скопировать второй уровень.С оператором Spread, например,
let secondCollection = collection.map(item => {
let newItem = {
...item
}
newItem.someData: 2
return newItem
})
console.log(collection) //[{someData: 1}]
console.log(secondCollection) //[{someData: 2}]
Это может разочаровать, и есть много способов избежать неприятностей.Normalization
это один хороший способ.Вот справочник по избыточным состояниям:
https://redux.js.org/recipes/structuring-reducers/normalizing-state-shape
Если вам удобно использовать сторонние библиотеки, в lodash
есть метод cloneDeep
, который будет выполнять копирование глубоких уровней дляВы:
https://lodash.com/docs/4.17.11#cloneDeep
Для вашей корзины обновлений:
Это может быть значительно упрощено.Совершенно не нужно брать дубликаты в массиве и for
проходить через него и далее.
Попробуем упростить его:
//assuming the carProducts state as
[
{
id: 1,
quantity: 2,
},
{
id: 2,
quantity: 2,
}
]
let newState = carProducts.map(item => {
let newItem = {...item} //or _.cloneDeep(item)
newItem.quantity = item.quantity + 1 //or add up the payload
return newItem
})
Вы также должны разделить продукты,carProducts и т. д. указаны в другом редукторе для простоты и большего контроля.
Пожалуйста, не стесняйтесь комментировать, если у вас есть что-то неясное:)