You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中如何在Navbar组件中复用购物车按钮?

解决方案:抽离可复用购物车按钮组件

核心思路是把购物车按钮和关联的弹窗逻辑抽成独立组件,完全依赖CartContext获取数据和状态,这样无论在Book组件还是全局Navbar里都能直接复用,且购物车数据更新时会自动同步渲染。

步骤1:创建独立的CartButton组件

把原Book组件里的购物车按钮、弹窗逻辑全部抽离成单独组件:

import React, { useState, useContext } from "react";
import { Button, Modal } from "react-bootstrap";
import { CartContext } from "./CartContext";
import CartProduct from "./CartProduct";

const CartButton = () => {
  const [show, setShow] = useState(false);
  const handleClose = () => setShow(false);
  const handleShow = () => setShow(true);
  const cart = useContext(CartContext);

  // 计算购物车商品总数
  const productCount = cart.items.reduce(
    (sum, product) => sum + product.quantity,
    0
  );

  return (
    <>
      <Button
        className="custom__button"
        variant="success"
        onClick={handleShow}
      >
        Cart ({productCount} Items)
      </Button>

      <Modal show={show} onHide={handleClose}>
        <Modal.Header closeButton>
          <Modal.Title>Your Booking</Modal.Title>
        </Modal.Header>
        <Modal.Body>
          {productCount > 0 ? (
            <>
              <p>Items in your cart:</p>
              {cart.items.map((currentProduct, idx) => (
                <CartProduct
                  key={idx}
                  id={currentProduct.id}
                  quantity={currentProduct.quantity}
                />
              ))}
              <h1>Total: {cart.getTotalCost().toFixed(2)}</h1>
              <button 
                className="custom__button" 
                onClick={()=> window.open("https://form.jotform.com/231252553810347")}
              >
                Complete Your Order!
              </button>
            </>
          ) : (
            <h1>There are no items in your cart!</h1>
          )}
        </Modal.Body>
      </Modal>
    </>
  );
};

export default CartButton;

步骤2:修改原Book组件,复用CartButton

移除原Book组件里的按钮和弹窗代码,直接导入并使用新组件:

import React from "react";
import TrackVisibility from "react-on-screen";
import { Row, Col, Navbar } from "react-bootstrap";
import { productsArray } from "./productsStore";
import ProductCard from "./ProductCard";
import CartButton from "./CartButton";
import "./Store.css";

const Book = () => {
  return ( 
    <>
      <div
        className="app__store app__bg section__padding flex__center"
        id="booking"
      >
        <Navbar expand="sm" className="app__bg" variant="dark">
          <Navbar.Brand href="/book" className="headtext__cormorant">
            Book a Session{" "}
            <p className="p__opensans"></p>
          </Navbar.Brand>

          {/* 复用抽离后的购物车按钮 */}
          <CartButton />
        </Navbar>
      </div>
      <div className="app__bg app__wrapper section__padding">
        <Row xs={1} md={2} lg={4} className="g-4">
          {productsArray.map((product, idx) => (
            <Col align="center" key={idx}>
              <TrackVisibility partialVisibility>
                {({ isVisible }) => (
                  <div
                    className={
                      isVisible ? "animate__animated animate__flipInY" : ""
                    }
                  >
                    <ProductCard product={product} />
                  </div>
                )}
              </TrackVisibility>
            </Col>
          ))}
        </Row>
      </div>
    </>
  );
};

export default Book;

步骤3:在全局Navbar中使用CartButton

直接在你的全局导航栏组件里导入并添加CartButton:

import React from "react";
import { Navbar, Container, Nav } from "react-bootstrap";
import CartButton from "./CartButton";

const AppNavbar = () => {
  return (
    <Navbar bg="dark" variant="dark" expand="lg">
      <Container>
        <Navbar.Brand href="/">Home</Navbar.Brand>
        <Navbar.Toggle aria-controls="basic-navbar-nav" />
        <Navbar.Collapse id="basic-navbar-nav">
          <Nav className="me-auto">
            <Nav.Link href="/book">Book Session</Nav.Link>
            {/* 添加购物车按钮 */}
            <CartButton />
          </Nav>
        </Navbar.Collapse>
      </Container>
    </Navbar>
  );
};

export default AppNavbar;

关键注意事项

  • 确保Context作用范围:你的CartProvider必须包裹整个应用(比如在App.js里),否则CartButton无法获取购物车数据。
  • 状态更新的正确性:检查CartContext中的状态更新逻辑,必须通过创建新数组/对象的方式更新cart.items(不能直接修改原数组),这样React才能检测到状态变化并触发组件重新渲染。

内容的提问来源于stack exchange,提问作者Jay

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 08:57:24