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

2024-03-26

当用户单击“添加到购物车”按钮时,我尝试将商品添加到购物车页面。

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;

这是购物车页面。我要去的地方,渲染项目详细信息项目详情 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;

这是我的物品描述页面。我已经使用参数获取了项目,这是我发现对我来说更容易的唯一方法。

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;

这是我的应用程序页面

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

您在声明 React 组件时遇到问题,其中一些组件没有正确使用 props。function ItemDetail(handleClick) { ... }应该function ItemDetail({ handleClick }) { ... }, and const Discover = (props, params, handleClick) => { ... }可能应该是这样的const Discover = ({ params, handleClick, ...props }) => { ... }。 React 组件接收单个 props 对象参数。

handleChange in App也处于变异状态。

Solution

App

修复状态突变并确保 props 正确传递给路由组件。在检查添加到购物车时,使用商品 GUID 来搜索购物车,而不是浅层引用相等。更新购物车数量时,需要浅复制正在更新的购物车数组和购物车商品。尽可能使用功能状态更新,以确保它是从以前的状态更新的,而不是范围内关闭的任何陈旧状态值。

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

项目详情

访问/破坏handleClick正确支撑。传递该项目的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

正确访问/解构handleClick打回来。使用Link组件而不是原始锚点(<a />) 标签。锚标记将重新加载应用程序,这很可能不是您想要发生的情况。根据代码我怀疑你实际上并不需要这个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

不要将购物车总计存储在状态中,它很容易从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>
  );
};
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在反应中将商品添加到购物车页面 的相关文章

随机推荐