简体   繁体   English

如何在反应中将商品添加到购物车页面

[英]How can I add the item to cart page in react

I am trying to add the items to a cart page when a user clicks the add to cart button.当用户单击添加到购物车按钮时,我试图将项目添加到购物车页面。

import React from "react";
import "bootstrap";
import { useParams } from "react-router-dom";

function ItemDetail(handleClick) {
  const params = useParams();
  let { productCode, vendor, value}  = params;
  let item = {productCode, vendor, value};

  console.log(item);

  return (
    <>
      <div>
        <p>product id: {productCode}</p>
        <p>price: {value}</p>
        <p>vendor: {vendor}</p>
        <button onClick={() => handleClick(item)}>Add to Cart</button>
      </div>
    </>
  );
}

export default ItemDetail;

This is the cart page.这是购物车页面。 Where I am to, render the item details from Item Details Page.我要去的地方,从项目详细信息页面呈现项目详细信息。

import React, { useState, useEffect } from "react";

const Cart = ({ cart, setCart, handleChange }) => {
  const [price, setPrice] = useState(0);

  const handleRemove = (id) => {
    const arr = cart.filter((item) => item.id !== id);
    setCart(arr);
    handlePrice();
  };

  const handlePrice = () => {
    let ans = 0;
    cart.map((item) => (ans += item.amount * item.price));
    setPrice(ans);
  };

  useEffect(() => {
    handlePrice();
  });

  console.log(setCart);

  return (
    <article>
      {cart.map((item) => (
        <div className="cart_box" key={item.id}>
          <div>
            <button onClick={() => handleChange(item, 1)}>+</button>
            <button>{item.amount}</button>
            <button onClick={() => handleChange(item, -1)}>-</button>
          </div>
          <div>
            <span>{item.price}</span>
            <button onClick={() => handleRemove(item.id)}>Remove</button>
          </div>
        </div>
      ))}
      <div className="total">
        <span>Total Price of your Cart</span>
        <span>R - {price}</span>
      </div>
    </article>
  );
};

export default Cart;

This is my item description page.这是我的项目描述页面。 I have fetched the items using params, this is only way I found easier for me.我已经使用参数获取了项目,这是我发现对我来说更容易的唯一方法。

import React, { useState, useEffect } from "react";
import { Row, Col } from "react-bootstrap";
import StyledCard from "../components/Card";

const Discover = (props, params, handleClick) => {
  const token = "not-the-actual-token";
  const [result, setResult] = useState([]);

  useEffect(() => {
    fetch(
      "https://api.flash-internal.flash-group.com/ecommerceManagement/1.0.0/api/product/",
      {
        method: "GET",
        headers: { Authorization: `Bearer ${token}` },
      }
    )
      .then((res) => res.json())
      .then((json) => setResult(json));
  }, []);

  const cardStyle = {
    listStyle: "none",
    margin: 5,
    paddingLeft: 0,
    minWidth: 240,
  };
  return (
    <>
      <div className="latestdeals container my-5">
        <h1>All Products</h1>
        <Row className="hotcards">
          <Col className="colcard">
            {(result?.result || []).map((item) => (
              <div key={item.productCode} style={cardStyle}>
                <a href={`/itemDetail/${item.productCode}/${item.value}/${item.vendor}`}>
                  {" "}
                  <StyledCard
                    key={item.productCode}
                    name={item.vendor}
                    title={item.description}
                    price={item.value}
                    handleClick={handleClick}
                    item={item}
                  />
                </a>
              </div>
            ))}
          </Col>
        </Row>
      </div>
    </>
  );
};

export default Discover;

This is my App page这是我的应用页面

import "./index.scss";
import React, { useState } from "react";
import {
  BrowserRouter as Router,
  Route,
  Routes,
  useParams,
} from "react-router-dom";
import AllCategories from "./pages/all-catergories";
import Home from "./pages/home";
import Entertainment from "./pages/entertainment";
// import Cart from "./pages/_cart";
import Login from "./pages/login";
import Netflix from "./pages/netflix";
import Orders from "./pages/orders";
import SignUp from "./pages/sign-up";
// import Data2 from "./Data2";
import Products from "./pages/products";
// import Shop from "./components/Shop";
// import ProductDetail from "./pages/ProductDetail";
import Discover from "./pages/discover";
import ItemDetail from "./pages/itemDetail";
import Cart from "./pages/cart";

function App() {
  const [show, setShow] = useState(true);
  const [cart, setCart] = useState([]);

  const handleClick = (item) => {
    if (cart.indexOf(item) !== -1) return;
    setCart([...cart, item]);
  };

  const handleChange = (item, d) => {
    const ind = cart.indexOf(item);
    const arr = cart;
    arr[ind].amount += d;

    if (arr[ind].amount === 0) arr[ind].amount = 1;
    setCart([...arr]);
  };

  return (
    <Router>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="all-categories" exact element={<AllCategories />} />
        {/* <Route path="cart" exact element={<Cart />} /> */}
        <Route path="entertainment" exact element={<Entertainment />} />
        <Route path="login" exact element={<Login />} />
        <Route path="discover" exact element={<Discover />} />
        <Route path="netflix" exact element={<Netflix />} />
        <Route path="orders" exact element={<Orders />} />
        <Route path="sign-up" exact element={<SignUp />} />
        <Route path="products" element={<Products />} />
        <Route path="/itemDetail/:productCode/:value/:vendor" element={<ItemDetail />} />
        <Route path="/itemDetail/" element={<ItemDetail handleClick={handleClick}  />} />
        <Route path="/Cart/" exact element={<Cart cart={cart} setCart={setCart} handleChange={handleChange}/>} />
      </Routes>
    </Router>
  );
}

export default App;

Issues问题

You've issues declaring React components, several of them aren't using props correctly.您在声明 React 组件时遇到问题,其中有几个组件没有正确使用 props。 function ItemDetail(handleClick) {... } should be function ItemDetail({ handleClick }) {... } , and const Discover = (props, params, handleClick) => {... } should probably be something like const Discover = ({ params, handleClick, ...props }) => {... } . function ItemDetail(handleClick) {... }应该是function ItemDetail({ handleClick }) {... }const Discover = (props, params, handleClick) => {... }应该是const Discover = ({ params, handleClick, ...props }) => {... } React components receive a single props object argument. React 组件接收单个 props object 参数。

handleChange in App is also mutating state. App中的handleChange也在变异 state。

Solution解决方案

App应用程序

Fix the state mutation and ensure props are passed correctly to routed components.修复 state 突变并确保 props 正确传递给路由组件。 Use an item GUID to search the cart instead of shallow reference equality when checking to add to the cart.在检查添加到购物车时,使用项目 GUID 来搜索购物车而不是浅引用相等性。 When updating cart quantities it is necessary to shallow copy the cart array and cart items that are being updated.更新购物车数量时,有必要浅复制正在更新的购物车数组和购物车项目。 Use functional state updates whenever possible so it's ensured it's updating from the previous state and not any stale state value closed over in scope.尽可能使用功能性 state 更新,以确保它是从以前的 state 更新的,而不是在 scope 中关闭的任何陈旧的 state 值。

function App() {
  const [show, setShow] = useState(true);
  const [cart, setCart] = useState([]);

  const handleClick = (item) => {
    // Update cart item quantity if already in cart
    if (cart.some((cartItem) => cartItem.productCode === item.productCode)) {
      setCart((cart) =>
        cart.map((cartItem) =>
          cartItem.productCode === item.productCode
            ? {
                ...cartItem,
                amount: cartItem.amount + 1
              }
            : cartItem
        )
      );
      return;
    }

    // Add to cart
    setCart((cart) => [
      ...cart,
      { ...item, amount: 1 } // <-- initial amount 1
    ]);
  };

  const handleChange = (productCode, d) => {
    setCart((cart) =>
      cart.flatMap((cartItem) =>
        cartItem.productCode === productCode
          ? cartItem.amount + d < 1
            ? [] // <-- remove item if amount will be less than 1
            : [
                {
                  ...cartItem,
                  amount: cartItem.amount + d
                }
              ]
          : [cartItem]
      )
    );
  };

  return (
    <Router>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="all-categories" element={<AllCategories />} />
        <Route path="entertainment" element={<Entertainment />} />
        <Route path="login" element={<Login />} />
        <Route path="discover" element={<Discover />} />
        <Route path="netflix" element={<Netflix />} />
        <Route path="orders" element={<Orders />} />
        <Route path="sign-up" element={<SignUp />} />
        <Route path="products" element={<Products />} />
        <Route
          path="/itemDetail/:productCode/:value/:vendor"
          element={<ItemDetail handleClick={handleClick} />}
        />
        <Route
          path="/Cart/"
          element={(
            <Cart
              cart={cart}
              setCart={setCart}
              handleChange={handleChange}
            />
          )}
        />
      </Routes>
    </Router>
  );
}

ItemDetail项目详情

Access/destructure the handleClick prop correctly.正确访问/解构handleClick道具。 Pass the item's productCode to the callback.将项目的productCode传递给回调。

function ItemDetail({ handleClick }) {
  const { productCode, vendor, value} = useParams();
  const item = { productCode, vendor, value };

  return (
    <div>
      <p>product id: {productCode}</p>
      <p>price: {value}</p>
      <p>vendor: {vendor}</p>
      <button onClick={() => handleClick(item)}>Add to Cart</button>
    </div>
  );
}

Discover发现

Correctly access/destructure the handleClick callback.正确访问/解构handleClick回调。 Use the Link component instead of the raw anchor ( <a /> ) tag.使用Link组件而不是原始锚点 ( <a /> ) 标签。 The anchor tag will reload the app which very likely isn't what you want to happen.锚标记将重新加载应用程序,这很可能不是您想要发生的事情。 Based on the code I suspect you don't actually need this handleClick since the ItemDetail component is passed it and adds to the cart根据代码,我怀疑您实际上并不需要此handleClick ,因为ItemDetail组件已传递给它并添加到购物车

import { Link } from 'react-router-dom';

const cardStyle = {
  listStyle: "none",
  margin: 5,
  paddingLeft: 0,
  minWidth: 240,
};

const Discover = () => {
  const token = "not-the-actual-token";
  const [result, setResult] = useState([]);

  useEffect(() => {
    fetch(
      "https://api.flash-internal.flash-group.com/ecommerceManagement/1.0.0/api/product/",
      {
        method: "GET",
        headers: { Authorization: `Bearer ${token}` },
      }
    )
      .then((res) => {
        if (!res.ok) {
          throw new Error('Network response was not OK');
        }
        return res.json();
      })
      .then((data) => setResult(data.result))
      .catch(error => {
        // handle any rejected Promises, errors, etc...
      });
  }, []);

  return (
    <div className="latestdeals container my-5">
      <h1>All Products</h1>
      <Row className="hotcards">
        <Col className="colcard">
          {result.map((item) => (
            <div key={item.productCode} style={cardStyle}>
              <Link to={`/itemDetail/${item.productCode}/${item.value}/${item.vendor}`}>
                <StyledCard
                  name={item.vendor}
                  title={item.description}
                  price={item.value}
                  item={item}
                />
              </Link>
            </div>
          ))}
        </Col>
      </Row>
    </div>
  );
};

Cart大车

Don't store the cart total in state, it is easily derived from the cart state.不要将购物车总数存储在 state 中,它很容易从cart state 中导出。

const Cart = ({ cart, setCart, handleChange }) => {
  const handleRemove = (productCode) => {
    setCart(cart => cart.filter(item => item.productCode !== productCode));
  };

  const price = cart.reduce((total, item) => total + item.amount * item.price, 0);

  return (
    <article>
      {cart.map((item) => (
        <div className="cart_box" key={item.id}>
          <div>
            <button onClick={() => handleChange(item.productCode, 1)}>+</button>
            <button>{item.amount}</button>
            <button onClick={() => handleChange(item.productCode, -1)}>-</button>
          </div>
          <div>
            <span>{item.price}</span>
            <button onClick={() => handleRemove(item.productCode)}>Remove</button>
          </div>
        </div>
      ))}
      <div className="total">
        <span>Total Price of your Cart</span>
        <span>R - {price}</span>
      </div>
    </article>
  );
};

编辑 how-can-i-add-the-item-to-cart-page-in-react

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM