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

React电商购物车删除商品报错:渲染时更新组件问题

解决购物车删除功能的组件更新警告问题

错误原因

你遇到的Cannot update a component (App) while rendering a different component (Cart)警告,核心问题出在删除按钮的onClick绑定上:

<button onClick={deleteProd(c.id)}>Eliminar</button>

这种写法会在Cart组件渲染时立即执行deleteProd(c.id),而非点击按钮时触发。deleteProd内部调用了setCart更新App组件的状态,此时Cart还在渲染流程中,就导致了跨组件更新的警告。

修复方案

  1. 修正onClick绑定方式:用箭头函数包裹,确保只有点击时才执行删除逻辑
  2. 使用函数式更新状态:避免闭包导致的旧cart值问题,确保基于最新状态更新购物车
  3. 优化计算逻辑(可选):用useMemo缓存newCart、finalSum等计算结果,减少不必要的重复计算

修改后的完整代码

import React, { useMemo } from "react";
import Navbar from "./Navbar";
import { Link } from "react-router-dom";
import Footer from "./Footer";

function Cart({ cart, setCart }) {
  // 用useMemo缓存计算结果,避免每次渲染重复计算
  const newCart = useMemo(() => cart.flatMap((c) => c), [cart]);
  
  const finalSum = useMemo(() => {
    const sum = newCart.reduce((total, item) => {
      const priceNum = parseInt(item.price.replaceAll('.', ''), 10);
      return total + priceNum;
    }, 0);
    return sum.toLocaleString();
  }, [newCart]);

  function handleSubmit(e) {
    e.preventDefault();
    localStorage.clear();
    window.location.reload();
  }

  function deleteProd(id){
    // 使用函数式更新,确保拿到最新的cart状态
    setCart(prevCart => {
      const updCart = prevCart.flatMap(c => c).filter(e => e.id !== id);
      localStorage.setItem('cart', JSON.stringify(updCart));
      return updCart;
    });
  }

  return (
    <>
      <Navbar />
      <h1>Carrito de Compras</h1>
      <div className="cartWrapper">
        {newCart.map((c) => (
          <div className="cartProd" key={c.id}> {/* 给列表项添加key,符合React规范 */}
            <img src={c.img} alt={c.prod} /> {/* 补充alt文本,提升可访问性 */}
            <h1>{c.prod}</h1>
            <h2>precio: ${c.price}</h2>
            <Link to={`/products/${c.id}`}>Ver producto</Link>
            {/* 修正onClick绑定,点击时才执行删除 */}
            <button onClick={() => deleteProd(c.id)}>Eliminar</button>
          </div>
        ))}
        <div className="right-bar">
          <button onClick={handleSubmit}>Vaciar Carrito</button>
          <h1>Total: ${finalSum}</h1>
        </div>
      </div>
      <Footer />
    </>
  );
}

export default Cart;

额外说明

  • 给列表项添加key={c.id},避免React列表渲染的额外警告
  • 补充图片的alt文本,提升页面可访问性
  • 用reduce替代forEach计算总价,代码更简洁高效

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 17:21:07