我正在使用下面的reducer添加产品,删除它们,并将它们添加到购物车。我希望'ADD_TO_CART'
操作在调度时将一个项目添加到购物车,但如果一个项目已经在购物车中,我希望将其增加1。但是,该方法将购物车项增加2而不是1
export default (state, action) => {
switch (action.type) {
case 'ADD_PRODUCT':
return {
...state,
products: [action.payload, ...state.products]
}
case 'DELETE_PRODUCT':
return {
...state,
products: state.products.filter(product => product.id !== action.payload)
}
case 'ADD_TO_CART':
if (state.cart.some(cartItem => cartItem.id === action.payload.id)) {
const updatedItemIndex = state.cart.findIndex(cartItem => cartItem.id === action.payload.id)
let cartItems = [...state.cart]
let itemToUpdate = cartItems[updatedItemIndex]
itemToUpdate.quantity++
return { ...state, cart: cartItems }
} else {
const newItem = { ...action.payload, quantity: 1 }
return { ...state, cart: [...state.cart, newItem] }
}
default:
return state
}
}
这是调度操作的代码
function addToCart(product) {
dispatch({
type: 'ADD_TO_CART',
payload: product
})
}
我正在调用以下组件中的操作
import React, { useContext } from 'react'
import { ProductContext } from './ProductContext'
export const ProductCard = ({ product }) => {
const { deleteProduct, addToCart } = useContext(ProductContext)
const handleDelete = () => {
deleteProduct(product.id)
}
const handleCart = () => {
addToCart(product)
}
return (
<div className='product__card'>
<h3>{product.productName}</h3>
<p>{product.price}</p>
<button className='button'>View Product</button>
<button onClick={handleCart} className='button'>Add to Cart</button>
<button onClick={handleDelete} className='button'>Delete</button>
</div>
)
}
4条答案
按热度按时间mwkjh3gx1#
尝试将数量从数字更改为空报价。
snvhrwxg2#
你搞错了你改变了你的状态。
修复:创建一个新项目,并复制数据与传播运算符,并删除旧的。
lrl1mhuk3#
我遇到了同样的问题,情况非常相似,目前的答案都没有帮助我。因此我只能推荐
被改成
我知道这不是解决这个问题的正确方法,但功能工作,你可以改变它以后当你会找到解决方案
kpbpu0084#
问题
这里的问题是状态突变。cart数组是浅复制的,但
itemToUpdate
* 仍然 * 是对前一状态的对象的引用,itemToUpdate.quantity++
改变了这个对象引用。reducer函数可能被调用两次,作为
React.StrictMode
组件检测意外副作用的一部分。以下是文档的一个片段,重点是我的:
严格模式不能自动为您检测副作用,但它可以通过使它们更具确定性来帮助您发现它们。这是通过***故意双重调用***以下函数实现的:
constructor
、render
和shouldComponentUpdate
方法getDerivedStateFromProps
方法setState
的第一个参数)useState
、useMemo
或***useReducer
***的函数有关当前文档中的相同/类似信息,请参阅在开发中修复通过双重渲染发现的错误。
解决方案
更新状态时,浅复制所有正在更新的状态**和嵌套状态***。除了浅复制
cart
数组之外,还应该将正在更新的购物车项目浅复制到一个新的对象引用中, 然后 * 覆盖正在更新的属性。示例:
我知道Redux并没有在这篇文章的代码中使用,但是他们有一个很棒的文档,关于Immutable Update Patterns的原因和应用,你应该看看。