You need to enable JavaScript to run this app. React购物车通过NavLinks跳转后useState存储的商品数量重置如何解决
优惠活动
大模型
产品
解决方案
定价
更多

React购物车通过NavLinks跳转后useState存储的商品数量重置如何解决

问题根因
  • 单商品数量状态托管层级太低:你当前将每件商品的数量itemCount存在CartItem组件内部的useState中,通过NavLinks跳转页面时,购物车相关组件会被卸载,内存中的组件内部状态会被清空,返回页面后组件重新挂载,就会回到你写死的初始值0。
  • 父子组件状态脱节:你在CartPage遍历cartItems渲染子组件时,已经把每个商品的count作为itemCount props传给了CartItem,但子组件完全没有使用这个传入值初始化状态,反而硬编码了初始值为0。
修复方案

第一步:调整状态托管逻辑,把单商品数量状态提升到上层

所有和购物车相关的状态(商品列表cartItems、总数量cartCount、总金额cartTotal)统一放在上层组件(比如App.jsx,或者你封装的购物车上下文Provider)托管,不要分散在子组件内部。
新增更新单商品数量的方法,向下传递给CartPage再传到CartItem,上层组件示例逻辑如下:

// 上层组件(如App.jsx)示例逻辑
const [cartItems, setCartItems] = useState([
  // 你的初始商品列表,每个项带count字段
  {id: 1, name: '商品1', price: 10, count: 0},
  {id: 2, name: '商品2', price: 20, count: 0}
])
const [cartCount, setCartCount] = useState(0)
const [cartTotal, setCartTotal] = useState(0)

// 新增:更新指定商品的数量
const updateItemCount = (itemIndex, delta) => {
  const newCartItems = [...cartItems]
  const targetItem = newCartItems[itemIndex]
  // 避免数量减到负数
  const newCount = Math.max(0, targetItem.count + delta)
  if (newCount === targetItem.count) return
  // 更新单商品数量
  targetItem.count = newCount
  setCartItems(newCartItems)
  // 同步更新总数量、总金额
  setCartCount(prev => prev + delta)
  setCartTotal(prev => prev + delta * targetItem.price)
}

将updateItemCount作为props传给CartPage即可。

第二步:修改CartPage.jsx,把商品索引和更新方法传给子组件

import React from "react";
import CartItem from "../CartItem/CartItem";
import "./CartPage.css";

const CartPage = (props) => {
  return (
    <div className="cart-page">
      <h3 className="cart-title">Shopping Cart</h3>
      <div className="cart-info">
        <div className="items-container">
          <div className="items-header">
            <h5>PRODUCT</h5>
            <h5>QUANTITY</h5>
            <h5>PRICE</h5>
          </div>
          {props.cartItems.map((item, index) => {
            return (
              <CartItem
                key={index}
                name={item.name}
                price={item.price}
                itemCount={item.count}
                // 把当前商品索引和更新方法传给子组件
                updateItemCount={(delta) => props.updateItemCount(index, delta)}
              />
            );
          })}
        </div>
        <div className="order-summary">
          <h5>Order Summary</h5>
          <hr />
          <h6>Items</h6>
          <p>{props.cartCount}</p>
          <h6>Total Price</h6>
          <p>${props.cartTotal.toFixed(2)}</p>
          <button>Checkout</button>
        </div>
      </div>
    </div>
  );
};

export default CartPage;

第三步:修改CartItem.jsx,删除内部状态,直接用props传入的值和方法

import React from "react";
import "./CartItem.css";

const CartItem = (props) => {
  return (
    <div className="item">
      <p>{props.name}</p>
      <p>
        <i
          className="bi bi-dash-square-fill minus-item"
          onClick={() => props.updateItemCount(-1)}
        ></i>
        {props.itemCount}
        <i
          className="bi bi-plus-square-fill add-item"
          onClick={() => props.updateItemCount(1)}
        ></i>
      </p>
      <p>{props.price}</p>
      <p>Delete</p>
    </div>
  );
};

export default CartItem;

可选:页面刷新也保留状态

如果需要浏览器刷新后购物车状态也不丢失,可以在更新购物车状态的同时,将cartItems、cartCount、cartTotal存入localStorage,组件初始化时优先从localStorage读取值:

// 上层组件初始化状态时从localStorage读取
const [cartItems, setCartItems] = useState(
  JSON.parse(localStorage.getItem('cartItems')) || []
)
const [cartCount, setCartCount] = useState(
  Number(localStorage.getItem('cartCount')) || 0
)
const [cartTotal, setCartTotal] = useState(
  Number(localStorage.getItem('cartTotal')) || 0
)

// 每次更新购物车状态时同步存入localStorage
const updateItemCount = (itemIndex, delta) => {
  // 原有逻辑不变
  // ...
  setCartItems(newCartItems)
  const newCountTotal = cartCount + delta
  const newPriceTotal = cartTotal + delta * targetItem.price
  setCartCount(newCountTotal)
  setCartTotal(newPriceTotal)
  // 新增:同步存本地
  localStorage.setItem('cartItems', JSON.stringify(newCartItems))
  localStorage.setItem('cartCount', String(newCountTotal))
  localStorage.setItem('cartTotal', String(newPriceTotal))
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.08 00:12:02