获取所选项目及其计数 [英] Get selected item and its count

查看:20
本文介绍了获取所选项目及其计数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试制作像

请帮助我在导航到购物车(袋子)页面时实现显示所选产品及其各自数量的结果.我为此苦苦挣扎了很长时间.所以我谦虚地请求您帮助我找到正确的解决方案.. 提前非常感谢..

解决方案

问题

  1. 您有多个 AppProvider 组件,每个组件都为其封装的子组件提供不同的上下文.
  2. 初始 AppContext 形状与 实际 作为上下文值传递的形状不匹配.
  3. cartItems 状态未作为数组维护.
  4. 其他各种问题和模式

解决方案

  1. 删除所有无关的 AppProvider 提供程序组件,只使用一个将整个应用程序包装在 _app.js 中.

    import { AppProvider } from "../components/context/AppContext";导出默认类 TailwindApp 扩展 App {使成为() {const { 组件,pageProps } = this.props;返回 (<应用程序提供者><组件 {...pageProps}/></AppProvider>);}}

  2. 修复上下文以具有与提供的值匹配的初始值.修复状态更新程序以正确管理 cartItems 数组.当 cartItems 数组状态更新时,使用 useEffect 挂钩计算派生的总项目计数状态.正确添加和更新项目/产品数量,当数量达到0时删除项目.

    import React, { useState, useEffect } from "react";导出 const AppContext = React.createContext({购物车:0,购物车项目:[],setCart: () =>{},addToCart: () =>{},removeFromCart: () =>{}});export const AppProvider = (props) =>{const [cart, setCart] = useState(0);常量 [cartItems, setCartItems] = useState([]);使用效果(() => {setCart(cartItems.reduce((count, {数量}) => 数量 + 数量, 0));}, [cartItems]);const addToCart = (product) =>{setCartItems((项目) => {if (items.find(({ id }) => id === product.id)) {返回 items.map((item) =>item.id === product.id?{...物品,数量:item.quantity + 1}: 物品);} 别的 {返回 [...项目,{...产品,数量:1}];}});};const removeFromCart = (product) =>{setCartItems((项目) => {const foundItem = items.find(({ id }) => id === product.id);if (foundItem?.quantity > 1) {返回 items.map((item) =>item.id === product.id?{...物品,数量:item.quantity - 1}: 物品);} 别的 {return items.filter(({ id }) => id !== product.id);}});};返回 (<AppContext.Provider value={{ 购物车, addToCart, removeFromCart, cartItems }}>{props.children}</AppContext.Provider>);};

  3. Products.js 中移除所有本地项目计数状态,数量可以从上下文中的状态访问.有条件地呈现添加项目"以及项目计数上的递增/递减按钮.

    从next/link"导入链接;从反应"中导入 { useContext };从./context/AppContext"导入{ AppContext};const Product = (props) =>{常量 { 产品 } = 道具;const contextData = useContext(AppContext);常量计数 =contextData.cartItems.find(({ id }) => id === product.id)?.quantity ??0;const addToCart = (product) =>() =>{contextData.addToCart(product);};const removeFromCart = (product) =>() =>{contextData.removeFromCart(product);};返回 (...{数数 ?(...{数数}...) : (...<span className="标签">添加</span>...)}</div></div>);};

  4. Cart.js 中,您可以导入和使用上下文来渲染和显示购物车项目.

    import { useContext } from "react";从../components/context/AppContext"导入{ AppContext};常量购物车 = () =>{常量 { 购物车, cartItems } = useContext(AppContext);返回 (

    <h1>购物车页面 </h1><h2>商品总数:{cart}</h2><p><ul>{cartItems.map(({ id, name, quantity }) => (<li key={id}>{名称}:{数量}</li>))}</ul></p></div>);};

注意:请注意,id 属性已添加到您的 products 数组中的所有商品/产品中以进行匹配/识别它们是一项更容易的任务.

演示

I am trying to make a shopping cart app like this site but using reactjs.

index.js: (Sending each product to product component)

        {products.length > 0
          ? products.map((product) => (
              <Product key={product.id} product={product} />
            ))
          : ""}

components/product.js:

<div>
    {product?.price}
   <h3>
      {product.name ? product.name : ""}
   </h3>
   <div dangerouslySetInnerHTML={{ __html: product?.description }} />
</div>

Also I have the ADD button UI switch code and that will look like,

Before clicking add button,

------------
| ADD     +|
------------

After clicking add button,

-----------------
| -  {count}   +|
-----------------

Things are fine as of now and the respective count(s) on each product individually gets added in home page.

Also with the help of contextApi made an AppContext and updated the cart like,

  const addToCart = (product) => {
    if (+cart >= 0) {
      setCart(+cart + 1);
      setCartItems(product);
    }
  };

In nav.js, I am getting the updated count of the products but when I click on the bag menu (Which is a cart page) , I am unable to fetch the context.

Expected Result

While visiting the cart page (On click of the bag menu in header), the page would display the so far selected product (with name and description) along with their quantity respectively.

Current Result:

Unable to get the appcontext data and display the selected product along with the quantity.

Working Snippet:

Please kindly help me to achieve the result of displaying the selected product and its respective quantity while navigating to cart (bag) page.. I am struggling with this for long.. So I humbly request you to help me with right solution.. Big thanks in advance..

解决方案

Issues

  1. You've multiple AppProvider components each providing a different context to their wrapped children.
  2. The initial AppContext shape doesn't match what is actually passed as the context's value.
  3. The cartItems state isn't maintained as an array.
  4. Other various issues and patterns

Solution

  1. Remove all the extraneous AppProvider provider components, use just one to wrap your entire app in _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>
        );
      }
    }
    

  2. Fix the context to have an initial value that matches the provided value. Fix the state updaters to correctly manage the cartItems array. Use an useEffect hook to compute the derived total item count state when the cartItems array state updates. Correctly add and update item/product quantities, and remove item when quantity reaches 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>
      );
    };
    

  3. In Products.js remove all the local item count state, quantities can be accessed from state in the context. Conditionally render the "Add Item" and increment/decrement buttons on the item count.

    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>
      );
    };
    

  4. In Cart.js you can import and consume the context to render and display the cart items.

    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>
      );
    };
    

Note: Please note that an id property was added to all items/products in your products array to make matching/identifying them a much easier task.

Demo

这篇关于获取所选项目及其计数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆