每当我单击add to cart按钮时,操作就会被触发,但redux状态不会被更新(初始状态没有改变,但操作被触发)。
const CartScreen = () => {
const { id } = useParams();
const { search } = useLocation();
const [searchParms] = useSearchParams();
const productId = id;
const qty = search ? Number(search.split("=")[1]) : 1;
const dispatch = useDispatch()
useEffect(() => {
if (productId){
dispatch(addToCart(productId, qty))
}
}, [dispatch, productId, qty])
return (
<div>
<h1>Add to CART</h1>
</div>
);
};
export default CartScreen手推车动作
export const addToCart = (id, qty) => async (dispatch, getState) =>{
const {data} = await axios.get(`http://127.0.0.1:8000/api/products/${id}`)
dispatch({
type: CART_ADD_ITEM,
payload:{
product:data._id,
name:data.name,
image:data.image,
countInStock:data.countInStock,
qty
}
})
localStorage.setItem('cartItems', JSON.stringify(getState().cart.cartItems))
}手推车减速器
export const cartReducer = (state = { cartItems: []}, action) =>{
switch(action.type){
case CART_ADD_ITEM:
const item = action.payload
const existItem = state.cartItems.findIndex(x => x.product === item.product)
if (existItem){
return{
...state,
cartItems: state.cartItems.map(x =>
x.product === existItem.product ? item : x)
}
} else{
return{
...state,
cartItems:[...state.cartItems, item]
}
}
default:
return state
}
}Redux商店
const reducer = combineReducers({
productList: productListReducer,
productDetails: productDetailsReducer,
cart: cartReducer,
})
const initialState = {
cart:{cartItems:cartItemsFromStorage}
};
const middleware = [thunk];
const store = createStore(
reducer,
initialState,
composeWithDevTools(applyMiddleware(...middleware))
);从redux工具中,我可以看到我触发的操作。因为当我在console.log item in const item=action.payload中从浏览器控制台中获得特定项时,cartItem redux状态保持在初始值,因此没有更新
发布于 2021-12-24 14:03:18
Array.prototype.find()- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find
Array.prototype.findIndex()- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex
使用Array.prototype.findIndex()基本上会查找并返回第一个查找项的索引,如果没有找到,则返回-1。而Array.prototype.find()返回数组中与所提供的条件相匹配的第一个元素。
export const cartReducer = (state = { cartItems: [] }, action) => {
switch(action.type){
case CART_ADD_ITEM:
const item = action.payload;
// use Array.prototype.find() instead
// see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find
const existItem = state.cartItems.find(x => x.product === item.product);
if (existItem){
return{
...state,
cartItems: state.cartItems.map(x =>
x.product === existItem.product ? item : x)
};
} else{
return{
...state,
cartItems: [...state.cartItems, item]
};
}
default:
return state;
}
};发布于 2021-12-28 17:31:11
问题是,您正在搜索现有产品,然后使用索引值作为布尔条件(array.findIndex)返回查找索引(),然后返回。
这不会像你所期望的那样工作,因为所有的非零数字都是真实的,而0则是假的。这意味着,如果没有任何购物车项目产品与返回的-1相匹配,那么逻辑将将其视为一个现有项。这在稍后通过array.map更新购物车时更加复杂..。如果existItem是-1 --这意味着没有匹配的产品,新的state.cartItems将是一个新的数组,但它将不包含新的item对象。换句话说,它将是,只是,一个以前状态的副本。
cartItems最初是以空数组开始的,因此existItem将始终在向购物车中添加项时返回-1。
如果产品确实存在于cartItems数组中,并且它是第0元素,则会发生另一个无意中的错误。existItem将等于0,因此是falsey,item将作为副本添加到cartItems数组中。
@Chigbogu对于array.findIndex和array.find的使用是正确的,不过如果您只是在检查购物车条目数组是否有该项,我建议您使用array.some。这表示您正在显式地使用布尔值。将existItem重命名为hasItem或类似的名称,以便该名称还指示一个布尔值(这是按照惯例)。
export const cartReducer = (state = { cartItems: []}, action) =>{
switch(action.type) {
case CART_ADD_ITEM: {
const newItem = action.payload;
const hasItem = state.cartItems.some(item => item.product === newItem.product);
if (hasItem) {
return {
...state,
cartItems: state.cartItems.map(item =>
item.product === newItem.product ? newItem : item
)
}
} else {
return {
...state,
cartItems: [...state.cartItems, newItem]
}
}
}
default:
return state;
}
};https://stackoverflow.com/questions/70469134
复制相似问题