javascript - 获取所选项目及其计数
问题描述
我正在尝试制作一个像这个网站一样的购物车应用程序,但使用reactjs。
index.js:(将每个产品发送到 product component
)
{products.length > 0
? products.map((product) => (
<Product key={product.id} product={product} />
))
: ""}
组件/product.js:
<div>
{product?.price}
<h3>
{product.name ? product.name : ""}
</h3>
<div dangerouslySetInnerHTML={{ __html: product?.description }} />
</div>
我也有添加按钮 UI 切换代码,看起来像,
在点击添加按钮之前,
------------
| ADD +|
------------
点击添加按钮后,
-----------------
| - {count} +|
-----------------
到目前为止一切都很好,每个产品的相应计数都单独添加到主页中。
还借助contextApi制作AppContext
并更新了购物车,例如,
const addToCart = (product) => {
if (+cart >= 0) {
setCart(+cart + 1);
setCartItems(product);
}
};
在nav.js中,我正在获取产品的更新计数,但是当我单击包菜单(这是一个购物车页面)时,我无法获取上下文。
预期结果
在访问购物车页面时(单击标题中的包菜单),该页面将分别显示迄今为止选择的产品(带有名称和描述)及其数量。
当前结果:
无法获取 appcontext 数据并显示所选产品以及数量。
工作片段:
请帮助我实现在导航到购物车(袋)页面时显示所选产品及其各自数量的结果。我为此苦苦挣扎了很长时间。所以我谦虚地请求您帮助我解决正确的问题。大提前致谢..
解决方案
问题
- 您有多个
AppProvider
组件,每个组件都为其包装的子组件提供不同的上下文。 - 初始形状与实际作为上下文值传递的
AppContext
形状不匹配。 - 状态不作为
cartItems
数组维护。 - 其他各种问题和模式
解决方案
删除所有无关的
AppProvider
提供程序组件,只使用一个将整个应用程序包装在_app.js
.import { AppProvider } from "../components/context/AppContext"; export default class TailwindApp extends App { render() { const { Component, pageProps } = this.props; return ( <AppProvider> <Component {...pageProps} /> </AppProvider> ); } }
修复上下文以具有与提供的值匹配的初始值。修复状态更新程序以正确管理
cartItems
阵列。当数组状态更新时,使用useEffect
挂钩计算派生的总项目计数状态。cartItems
正确添加和更新项目/产品数量,并在数量达到0时删除项目。import React, { useState, useEffect } from "react"; export const AppContext = React.createContext({ cart: 0, cartItems: [], setCart: () => {}, addToCart: () => {}, removeFromCart: () => {} }); export const AppProvider = (props) => { const [cart, setCart] = useState(0); const [cartItems, setCartItems] = useState([]); useEffect(() => { setCart(cartItems.reduce((count, { quantity }) => count + quantity, 0)); }, [cartItems]); const addToCart = (product) => { setCartItems((items) => { if (items.find(({ id }) => id === product.id)) { return items.map((item) => item.id === product.id ? { ...item, quantity: item.quantity + 1 } : item ); } else { return [ ...items, { ...product, quantity: 1 } ]; } }); }; const removeFromCart = (product) => { setCartItems((items) => { const foundItem = items.find(({ id }) => id === product.id); if (foundItem?.quantity > 1) { return items.map((item) => item.id === product.id ? { ...item, quantity: item.quantity - 1 } : item ); } else { return items.filter(({ id }) => id !== product.id); } }); }; return ( <AppContext.Provider value={{ cart, addToCart, removeFromCart, cartItems }}> {props.children} </AppContext.Provider> ); };
在
Products.js
删除所有本地项目计数状态时,可以从上下文中的状态访问数量。有条件地在项目计数上呈现“添加项目”和递增/递减按钮。import Link from "next/link"; import { useContext } from "react"; import { AppContext } from "./context/AppContext"; const Product = (props) => { const { product } = props; const contextData = useContext(AppContext); const count = contextData.cartItems.find(({ id }) => id === product.id)?.quantity ?? 0; const addToCart = (product) => () => { contextData.addToCart(product); }; const removeFromCart = (product) => () => { contextData.removeFromCart(product); }; return ( ... {count ? ( ... {count} ... ) : ( ... <span className="label">ADD</span> ... )} </div> </div> ); };
您可以在其中
Cart.js
导入和使用上下文以呈现和显示购物车项目。import { useContext } from "react"; import { AppContext } from "../components/context/AppContext"; const Cart = () => { const { cart, cartItems } = useContext(AppContext); return ( <div> <h1> Cart Page </h1> <h2>Total Item Count: {cart}</h2> <p> <ul> {cartItems.map(({ id, name, quantity }) => ( <li key={id}> {name}: {quantity} </li> ))} </ul> </p> </div> ); };
注意:请注意,已将id
属性添加到products
数组中的所有项目/产品中,以使匹配/识别它们变得更加容易。
演示
推荐阅读
- flask - 将 ckeditor5 添加到 Flask
- postgresql - 在postgresql的另一个数据库中调用视图?
- firefox - 内容脚本如何以及以何种方式在不同的网页之间共享内容范围的变量?
- javascript - 我想在javascript中使用for循环来组合两个数组的数据
- php - 有什么办法可以防止owncloud内存不足?
- leaflet - 传单:更改默认标题长度
- json - Scala Play 中的空序列化(隐式写入)
- powershell - Passing PowerShell data variables to Terraform scripts
- cmd - cmd.exe 无法运行除内置命令外的任何命令
- python - 如何使用python同时多次运行python脚本并在完成后全部终止