Redux中Reducer多次触发及console.log异常输出问题咨询
Redux运行机制疑问:删除单个商品时
console.log('hello')为何仍执行? 问题场景
购物车中有多个商品,删除单个商品时,明明有商品ID匹配进入了Reducer的if块,但console.log('hello')还是会被执行。此前曾因错误在if块外返回state而非product,导致删除操作触发后所有商品被删除的异常。
相关代码
Reducer中的INCREASE_QTY分支
case INCREASE_QTY: return state.map((product) => { if (product.id === action.payload.id) { return { ...product, data: { ...product.data, qty: product.data.qty + action.payload.qty, }, }; } console.log('hello') return product; });
Action Creator代码
export const increaseQty = (id, qty) => { return { type: INCREASE_QTY, payload: { id, qty, }, }; };
组件中的dispatch逻辑
import React from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { increaseQty } from '../redux/productSlice/actions'; import { deleteFromCart } from '../redux/cartSlice/actions'; const CartCard = ({ product }) => { const cart = useSelector((state) => state.cart); const dispatch = useDispatch(); const deleteHandler = (id) => { const correspondingProduct = cart.productInfo.find( (product) => product.id === id ); dispatch(deleteFromCart(correspondingProduct.id)); dispatch(increaseQty(correspondingProduct.id, correspondingProduct.qty)); }; return ( <div className="cartCard"> <div className="flex items-center col-span-6 space-x-6"> <img className="cartImage" src={product.data.image} alt="product" /> <div className="space-y-2"> <h4 className="cartName">{product.data.name}</h4> <p className="cartCategory">{product.data.category}</p> <p> BDT <span className="cartPrice">{product.data.price}</span> </p> </div> </div> <div className="flex items-center justify-center col-span-2 mt-4 md:justify-end md:mt-0"> <button className="removeFromCart" onClick={() => deleteHandler(product.id)} > <i className="text-lg text-red-400 fa-solid fa-trash"></i> </button> </div> </div> ); }; export default CartCard;
疑问解答
核心原因是你使用了Array.map()方法遍历整个state数组,数组中的每一个元素都会独立执行一次map的回调函数:
- 对于ID匹配的那个商品,会进入
if块直接返回新对象,不会执行后续的console.log; - 但数组中所有ID不匹配的商品,都会跳过
if块,执行console.log('hello')后返回原商品对象。
所以只要state数组里有多个元素,除了匹配的那一个,剩下的每个元素都会触发一次console.log,这是map方法的正常遍历行为,和Redux的底层运行机制无关。
另外补充你之前的错误:当你在if块外返回state而非product时,map的每一次迭代都会返回整个原state数组,最终Reducer会返回一个由多个原state数组嵌套组成的结构,彻底打乱了state的正常格式,导致后续渲染时购物车数据异常,表现为所有商品被“删除”。
内容的提问来源于stack exchange,提问作者Samiul Islam Shibly
相关产品推荐
相关产品推荐

