javascript - 太多的重新渲染/无限循环 - 在映射函数中设置状态
问题描述
我试图通过我的购物车中的项目进行映射,并将项目的 id 与数据对象中返回的 id 进行比较,然后在浏览器上显示一些信息,例如每个项目的数量等。我还试图添加一个总数购物车项目显示元素,但是,当我添加购物车中每个项目的数量(例如,一个项目的数量为 3,另一个项目的数量为 1 等)并尝试在映射函数中设置状态时,我得到一个重新渲染错误. 我从在线阅读中了解到,这是因为当您设置状态时,组件会重新呈现,但是,我不确定如何在不从函数内部设置状态的情况下使用购物车中的商品总数设置状态。
我还尝试在映射函数之外声明变量并在每次迭代时添加到该变量,但这也不起作用。
如果我在映射函数中控制台记录 cartItemsTotal,我会得到正确的值,即添加所有正在映射的项目的数量。
如果我在映射函数之外进行控制台记录,它始终为 0。这是因为范围吗?您不能在函数范围之外操作变量吗?
任何帮助表示赞赏。
谢谢
const CartIconSummary = ({data}) => {
const [cartQuantity, setCartQuantity] = useState()
const deleteCart = useCartDelete()
const cart = useCart()
let cartTotal = 0
let vat = cartTotal * .23.toFixed(2)
let cartItemsTotal = 0
const displayCartItems = () => {
setCartQuantity(cartItemsTotal)
return cart && cart.map((cartItem, index) => {
return data && data.map((dataItem) => {
if(cartItem.id === dataItem.id) {
cartTotal = cartTotal + dataItem.price * cartItem.quantity
vat = vat + (dataItem.price * cartItem.quantity) * .23
cartItemsTotal = cartItemsTotal + cartItem.quantity
setCartQuantity(cartItemsTotal)
return (
<div key={index} className={`${className}CartItemContainer`}>
<div className={`${className}ImageContainer`}>
<img className={`${className}Image`} src={data ? `${process.env.PUBLIC_URL}${dataItem.cartImage.slice(1)}` : ""} alt="cart-item-preview"/>
</div>
<div className={`${className}CartItemNamePriceContainer`}>
<div className={`${className}CartItemName`}>
{dataItem.shortName}
</div>
<div className={`${className}CartItemPrice`}>
${dataItem.price}
</div>
</div>
<div className={`${className}CartItemQuantity`}>
x {cartItem.quantity}
</div>
</div>
)
} else {
return ""
}
})
})
}
return (
<>
<div className={`${className}CartDeleteContainer`}>
<div className={`${className}CartQuantity`}> CART({cartQuantity ? cartQuantity : 0}) </div>
<div className={`${className}CartDelete`} onClick={() => deleteCart([])}> Remove all </div>
</div>
{displayCartItems()}
</>
)
}
解决方案
目前你setCartQuantity
在函数内部调用displayCartItems
,这意味着每当组件渲染时,函数displayCartItems
也会再次运行。这意味着当函数displayCartItems
执行时,它将改变状态cartQuantity
,setCartQuantity
如果状态改变,整个组件将重新渲染,这意味着displayCartItems
将再次执行。
为了解决这个问题,您应该使用useEffect
钩子并添加cartItemsTotal
依赖数组,以便setCartQuantity
仅在cartItemsTotal
更改时执行。
推荐阅读
- swift - 嵌套 withUnsafeBytes 调用不可避免?
- android - Firebase 云消息传递 nodejs SDK 无法访问 iOS 应用
- angular - 角度材料选项卡 - 仅在选择活动选项卡时加载/卸载组件
- java - 启动多个线程并收集结果
- kubernetes - 如何在 Kubernetes 集群中使用主节点作为工作节点?
- android - 使用 RecyclerViewAdapter 在 GridLayout 中显示 SQLite 数据时出现错误
- excel - 通过匹配两个工作表中的列值突出显示行中的差异
- javascript - 帖子请求页面请求缺少变量
- sql - 在 .net 程序集元数据上运行类似 SQL 的查询
- c# - SignalR 客户端方法没有被解雇