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

React类组件setState更新购物车总数总价报错排查

React类组件购物车功能报错修复

报错根因

  • 类型错误Cannot read properties of undefined (reading 'length')触发原因:
    • 构造函数内重复给this.state赋值,第一次定义的shoppingCart字段被第二次赋值完全覆盖,state中不存在cartItems属性,访问this.state.cartItems.length直接触发undefined读取错误
    • 代码中存在多处非法属性访问:从localStorage取出的cartItems是render内的局部变量,并未挂载到this.state下,this.cartItems属于完全不存在的实例属性
    • 存在拼写错误:数组累加方法reduce被错写为redeuce
    • 未做空值兜底:localStorage中不存在cart字段时,JSON.parse返回值为null,直接读取属性会触发报错
  • 性能警告[Violation] 'message' handler took 177ms触发原因:
    • 每次render执行时都同步读取localStorage做IO操作,重复执行无缓存的数组计算,长任务阻塞了浏览器主线程

修复后完整代码

import { Component } from 'react';

class Cart extends Component{
    constructor(props){
        super(props)
        // 统一初始化所有状态,禁止重复赋值state
        this.state = {
            cartItems: [],
            totalItems: 0,
            totalPrice: 0
        }
        // 绑定事件方法this指向
        this.handleDecrease = this.handleDecrease.bind(this);
        this.handleIncrease = this.handleIncrease.bind(this);
    }

    // 组件挂载完成后读取本地存储,不在render中做IO/计算操作
    componentDidMount() {
        const storedCart = JSON.parse(localStorage.getItem('cart')) || [];
        this.updateCartState(storedCart);
    }

    // 抽离公共状态更新逻辑,所有购物车变更统一走该方法
    updateCartState(items) {
        // 统一计算总数量、总价格,做兜底处理
        const totalItems = items.length;
        const totalPrice = items.reduce((sum, item) => sum + item.price * item.quantity, 0);
        // 必须调用setState触发视图更新
        this.setState({
            cartItems: items,
            totalItems,
            totalPrice
        });
        // 同步更新本地存储
        localStorage.setItem('cart', JSON.stringify(items));
    }

    // 减少商品数量逻辑
    handleDecrease(productId) {
        const updatedItems = this.state.cartItems.map(item => {
            if (item.id === productId && item.quantity > 1) {
                return {...item, quantity: item.quantity - 1}
            }
            return item;
        }).filter(item => item.quantity > 0); // 数量为0时移除商品
        this.updateCartState(updatedItems);
    }

    // 增加商品数量逻辑
    handleIncrease(productId) {
        const updatedItems = this.state.cartItems.map(item => {
            if (item.id === productId) {
                return {...item, quantity: item.quantity + 1}
            }
            return item;
        });
        this.updateCartState(updatedItems);
    }

    render(){
        // 统一从state解构取值,不访问不存在的实例属性
        const { cartItems, totalItems, totalPrice } = this.state;
        return(<>
            <div>
                <h2>YOUR CART</h2>
                <p># Of Items: <span>{totalItems}</span></p>
                <p>Total Price: <span>${totalPrice.toFixed(2)}</span></p>
                <p>Check Out</p>
            </div>
            <div className="container prod-cntr">
                <div className="row prod-row">
                {cartItems.map((element) => (
                    <div className="col-lg-3 prod-col" key={element.id}>
                    <div className="card card-container">
                        <img
                        src={element.image}
                        alt="product img"
                        className="prod-img"
                        />
                        <div className="card-body">
                        <p className="card-title">{element.product}</p>
                        <p className="card-text">{element.description}</p>
                        <p className="quantity">
                            <span className="decrease" onClick={() => this.handleDecrease(element.id)}>
                                <i className="fa-solid fa-minus"></i>
                            </span>
                            Quantity: {element.quantity}
                            <span className="increase" onClick={() => this.handleIncrease(element.id)}>
                                <i className="fa-solid fa-plus"></i> 
                            </span>
                        </p>
                        </div>
                    </div>
                    </div>
                ))}
                </div>
            </div>
        </>)
    }
}

export default Cart;

关键修复说明

  • 移除构造函数中重复的this.state赋值,所有状态字段统一初始化,从根源避免状态丢失
  • 禁止在render方法中执行IO操作、复杂计算:将localStorage读取逻辑移到componentDidMount生命周期,仅在组件挂载时执行一次,解决主线程阻塞的性能问题
  • 抽离统一的状态更新方法,所有购物车数据变更必须通过setState触发,符合React单向数据流要求,避免视图和状态不同步
  • 修正所有非法属性访问、拼写错误,增加空值兜底逻辑,从根源解决undefined读取报错
  • 补全加减数量按钮的交互逻辑,变更后自动重算总金额、总数量,同步更新本地存储

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 06:18:24