购物车中的初始数量和价格 React.js
Posted
技术标签:
【中文标题】购物车中的初始数量和价格 React.js【英文标题】:Initial Quantity and Price in Shopping Cart React.js 【发布时间】:2021-09-27 19:01:16 【问题描述】:所以我正在构建一个反应购物车。我能够添加总数量和总价格功能,但无法显示购物车中产品的初始价格和数量。产品是使用 axios 和使用 useState 存储它。
这是代码
const CartPage = (props) =>
const [cartProducts, setCartProducts] = useState([]);
const [totalQuantity,setTotalQuantity] = useState();
const [totalPrice,setTotalPrice] = useState(0);
const [loading,setLoading]= useState(false);
const enqueueSnackbar,closeSnackbar = useSnackbar();
const authCtx = useContext(AuthContext)
const token = authCtx.token;
const userId = authCtx.userId;
useEffect(() =>
setLoading(true)
let queryParams = '?auth=' + token + '&orderBy="userId"&equalTo="' + userId + '"';
axiosInstance.get('/Cart.json'+queryParams).then((response) =>
//console.log(response.data);
let fetchProductData = [];
for (let key in response.data)
fetchProductData.push(
...response.data[key],
productId: key,
);
//console.log(fetchProductData);
setCartProducts(fetchProductData);
setLoading(false)
);
,[token,userId]);
这是 totalPrice 和 Total Quantity 功能,它们在递增和递减计数器处理程序中调用
const totalQuantityHandler=()=>
const totalQuantityCount=cartProducts.reduce((total,product)=>
return total+product.quantity;
,0)
//console.log(totalQuantityCount)
setTotalQuantity(totalQuantityCount)
//console.log(cartProducts)
const totalPriceHandler=()=>
const totalPriceCount=cartProducts.reduce((total,product)=>
return total+product.price*product.quantity;
,0)
//console.log(totalPriceCount);
setTotalPrice(totalPriceCount);
const incrementCounterHandler = (index) =>
const updatedCart = [...cartProducts]
updatedCart[index].quantity++
setCartProducts(updatedCart);
totalQuantityHandler();
totalPriceHandler();
//console.log(cartProducts)
const decrementCounterHandler=(index)=>
const updatedCart = [...cartProducts]
updatedCart[index].quantity--
setCartProducts(updatedCart);
totalQuantityHandler();
totalPriceHandler();
所以这里是显示总数量和总价格的 JSX 部分代码
<React.Fragment>
cartProducts.map((product, index) =>
//console.log(product)
return (
<CartCard
key=product.id
Image=product.productImage
Title=product.productName
Price=product.price
Details=product.productDetails
removeFromCart=() => removeFromCartHandler("REMOVE",product.productId)
moveToFavorites=(event)=>moveToFavoritesHandler(event,product)
Quantity=product.quantity
incrementCounter=() => incrementCounterHandler(index)
decrementCounter=() => decrementCounterHandler(index)
onHandleCallBack=(value) => sizeChangeHandler(value,index)
/>
);
)
<Divider style= height: "2px", backgroundColor: "#000" />
<Box
display="flex"
alignItems="center"
justifyContent="flex-end"
padding="10px"
margin="20px"
marginBottom="0px"
>
<Typography variant="h6">
SubTotal(totalQuantity Items): Rs.totalPrice
</Typography>
</Box>
<ButtonGroup cancelled=()=>cartPageCancelledHandler() continued=()=>cartPageContinuedHandler()/>
</React.Fragment>
我尝试了很多东西,但它似乎不起作用。有没有更好的方法来实现它?
【问题讨论】:
你能分享你的jsx的html部分吗? 除了总数量和价格是派生状态,因此不应存储在状态中,您的实用程序函数对我来说看起来是正确的。问题是什么?什么时候调用这些函数? @Nayanshah 嘿,我已经添加了 JSX 的 HTML 部分,你可以看看! @DrewReese 嘿,这些函数在递增和递减处理函数中被调用,这些函数用于递增/递减数量。所以基本上问题是我从firebase获取产品,我想显示获取的产品数量和这些产品的总价格。我也应该能够增加或减少产品的数量。我已经编辑了问题的代码部分。您可以查看它! 【参考方案1】:问题
这里的问题是 React 状态更新是异步处理的,所以当您将更新加入到cartProducts
状态(即setCartProducts(updatedCart);
)时,它并没有使用将要更新的状态,而是使用状态从当前渲染周期开始。
我能够添加总数量和总价格功能,但是 无法显示当前产品的初始价格和数量 在购物车中。产品是使用 axios 从后端获取的,并且 使用 useState 存储它。
您不会在获取数据后调用实用程序函数,因此不会计算初始 totalQuantity
和 totalPrice
状态。
此外,在增加/减少数量时,您似乎也在改变您的购物车状态。
const incrementCounterHandler = (index) =>
const updatedCart = [...cartProducts]
updatedCart[index].quantity++ // <-- mutation
setCartProducts(updatedCart);
totalQuantityHandler();
totalPriceHandler();
//console.log(cartProducts)
const decrementCounterHandler=(index)=>
const updatedCart = [...cartProducts]
updatedCart[index].quantity-- // <-- mutation
setCartProducts(updatedCart);
totalQuantityHandler();
totalPriceHandler();
解决方案
使用依赖于cartProducts
数组的useEffect
挂钩来计算cartProducts
更新时的数量和价格状态,并从购物车更新程序函数中删除对实用程序函数的调用。这样,当 cartProducts
状态从其他挂载效果初始化时,以及购物车状态更新的任何其他时间,都会重新计算数量和价格。
useEffect(() =>
totalQuantityHandler();
totalPriceHandler();
, [cartProduces]);
您必须浅拷贝所有正在更新的状态和嵌套状态。
const incrementCounterHandler = (index) =>
setCartProducts(cart => cart.map((item, i) => i === index
? ...item, quantity: item.quantity + 1
: item
);
;
const decrementCounterHandler = (index) =>
setCartProducts(cart => cart.map((item, i) => i === index
? ...item, quantity: item.quantity - 1
: item
);
;
事实上,因为这两个函数本质上是相同的,所以我更喜欢并建议将它们结合起来并传入数量增量。我还建议使用柯里化函数来避免在附加回调时需要使用匿名函数。
const incrementCounterHandler = (index, value) => () =>
setCartProducts(cart => cart.map((item, i) => i === index
? ...item, quantity: item.quantity + value
: item
);
;
用法:
<CartCard
...
incrementCounter=incrementCounterHandler(index, 1)
decrementCounter=decrementCounterHandler(index, -1)
...
/>
我还建议不要将派生的数量和价格值存储在状态中。这些应该根据实际状态每次渲染计算。如果您担心CartPage
重新渲染但cartProducts
状态没有重新渲染时重新计算,那么您可以记住这些值。
const totalQuantity, totalPrice = useMemo(() =>
return cartProducts.reduce(( totalQuantity, totalPrice , price, quantity ) => (
totalQuantity: totalQuantity + quantity,
totalPrice: totalPrice + (quantity * price),
),
totalQuantity: 0,
totalPrice: 0,
);
, [cartProducts]);
【讨论】:
嘿,我了解您想要传达的内容,并按照建议实施了更改及其工作。非常感谢您的帮助! @SandeepM 太棒了,很高兴它对你有用。由于我的回答似乎有助于解决您的问题/问题,因此我邀请您也接受它(***.com/help/someone-answers)。不要忘记对您在 *** 上找到的有用问题、答案和 cmets 进行投票。干杯。以上是关于购物车中的初始数量和价格 React.js的主要内容,如果未能解决你的问题,请参考以下文章