所以我有两个按钮用于将项目添加到购物车中。该商品有两个价格(1/2公斤价格和1公斤价格(。我想当点击1/2公斤按钮时,它会添加价格为1/2公斤的物品,当点击1公斤按钮时会添加价格1公斤的物品。到目前为止,两个按钮都加了1/2公斤的价格,因为这是我在决定加1公斤之前唯一的价格。下面是我的代码:
附言:价格是1/2公斤的价格,价格2是1公斤的价格。
const CollectionItem = ({ item, addItem }) => {
const { name, price, price2, imageUrl } = item;
return (
<div className="collection-item">
<div className="image" style={{ backgroundImage: `url(${imageUrl})` }} />
<div className="collection-footer">
<span className="name">{name}</span>
<div className="prices">
<strong>
<span className="price">{price}</span>
</strong>
<strong>
<span className="price2">{price2}</span>
</strong>
</div>
</div>
<div className="add-buttons">
<CustomButton
className="custom-button"
onClick={() => addItem(item, 'price')}
inverted
>
Add 1/2kg
</CustomButton>
<CustomButton
className="custom-button"
onClick={() => addItem(item, 'price2')}
inverted
>
Add 1kg
</CustomButton>
</div>
</div>
);
};
const mapDispatchToProps = (dispatch) => ({
addItem: (item) => dispatch(addItem(item)),
});
addItem是我用来更新reducer的操作创建者,它使用了我创建的cartUtils文件中的以下函数来更新:
export const addItemToCart = (cartItems, cartItemToAdd) => {
const existingCartItem = cartItems.find(
(cartItem) => cartItem.id === cartItemToAdd.id
);
if (existingCartItem) {
return cartItems.map((cartItem) =>
cartItem.id === cartItemToAdd.id
? { ...cartItem, quantity: cartItem.quantity + 1 }
: cartItem
);
}
return [...cartItems, { ...cartItemToAdd, quantity: 1 }];
};
我的操作是:
export const addItem = (item) => ({
type: CartActionTypes.ADD_ITEMS,
payload: item,
});
我的减速器是:
case CartActionTypes.ADD_ITEMS:
return {
...state,
cartItems: addItemToCart(state.cartItems, action.payload),
};
我希望你们这些好人能帮助我!
我看到了两种可能的方法:
- 而不是addItem((,创建两个单独的函数,其中对于0.5公斤的onClick操作,将只使用item.price;对于1公斤的函数,将使用item.price2
或
- 在addItem((函数中添加第二个参数,这样就可以在特定操作中使用不同的价格,比如:
const addItem = (item, priceType) => {
switch (priceType) {
case 'price':
// 0,5kg
case 'price2':
// 1kg
default: //default case
}
}
...
<div>
<CustomButton
...
onClick={() => addItem(item, 'price')}
>
Add 1/2kg
</ CustomButton>
<CustomButton
...
onClick={() => addItem(item, 'price2')}
>
Add 1kg
</ CustomButton>
</div>
REDUX
我建议你使用没有反模式的方法1。我还添加了第二种方法,保持了原作者的思维方式。
方法1。无反模式
- 在React
CollectionItem
组件中使用mapStateToProps,这样您就可以从STORE中获得cartItems
作为道具 - 重写函数触发了onClick事件,这样它就可以对cartItems进行所有必要的更改,然后返回更新后的cartItemss列表
- Reducer只需要获取更新后的参数并将其传递给STORE,而不需要任何突变
const CollectionItem = ({ item, addItem, cartItems }) => {
const { name, price, price2, imageUrl } = item;
const addItemToList = (item, priceType) => {
// addItemToCart() logic
// cartItems argument is available as a props from STORE
addItem(updatedCartItems); //call action
}
return (
...
<CustomButton
...
onClick={() => addItemToList(item, 'price')}
>
Add 1/2kg
</ CustomButton>
)
}
const mapStateToProps = (state) => ({
cartItems: state.cartItems
});
const mapDispatchToProps = (dispatch) => ({
addItem: (updatedCartItems) => dispatch(addItem(updatedCartItems)),
});
export default connect(mapStateToProps, mapDispatchToProps)(CollectionItem);
动作创建者
export const addItem = (updatedItems) => ({
type: CartActionTypes.ADD_ITEMS,
payload: updatedItems,
});
减速器
case CartActionTypes.ADD_ITEMS:
return {
...state,
cartItems: action.payload, // PURE REDUCER
};
方法2。减速器中的防图案
由于您更新了addItem(item, 'price')
,因此它接收到两个参数,现在是时候更新您的动作创建者和减速器了,因此它将能够接受第二个参数'price'
或'price2'
。
动作创建者-添加priceType
export const addItem = (item, priceType) => ({
type: CartActionTypes.ADD_ITEMS,
payload: item,
priceType
});
减速器-传递priceType
小心!在减速器内部使用addItemToCart()
是反模式的。根据redux文档,您永远不应该在reducer内部更改参数,它应该保持纯粹。
case CartActionTypes.ADD_ITEMS:
return {
...state,
cartItems: addItemToCart(state.cartItems, action.payload, action.priceType),
};
那么addItemToCart(cartItems, cartItemToAdd, priceType)
可以使用switch(priceType)
,所以它将不同的价格类型。