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

React项目中TypeError: Cannot add property Quantity, object is not extensible错误的排查与修复咨询

Fix for TypeError: Cannot add property Quantity, object is not extensible

Let's break down what's causing your error and how to fix it step by step.

Key Issues in Your Code

  • Nested Ref Structure: Your custom hook returns an array containing a ref, and you wrap that result in another useRef in App.jsx. This means you're not accessing the actual items array when trying to modify it.
  • Storing the Wrong Data: In your custom hook's useEffect, you're stringifying the ref object itself (JSON.stringify(itemsInCart)) instead of the array inside itemsInCart.current. This stores a ref structure in localStorage, not your actual cart items.
  • Directly Modifying Non-Extensible Objects: Even if you fix the ref issue, if the objects from localStorage are non-extensible (e.g., frozen before storage), modifying them directly will throw an error.

Fixed Code

Step 1: Correct the Custom Hook (App.jsx)

Rewrite your custom hook to properly manage the ref and localStorage, following React's custom hook conventions:

import { useRef, useEffect } from 'react';

// Custom hooks should start with "use"
const useItemsCartWithLocalStorage = (storageKey) => { 
  // Initialize ref with localStorage data or empty array
  const itemsInCartRef = useRef(JSON.parse(localStorage.getItem(storageKey)) || []); 

  useEffect(() => { 
    // Save the actual array (ref.current) to localStorage
    localStorage.setItem(storageKey, JSON.stringify(itemsInCartRef.current)); 
  }, [itemsInCartRef.current, storageKey]); 

  return itemsInCartRef; 
}; 

function App() { 
  // Get the ref directly from the hook (no extra useRef!)
  const itemsInCartRef = useItemsCartWithLocalStorage('itemsQuantityString'); 
  return <Files itemsInCartRef={itemsInCartRef} />; 
}

Step 2: Update Files.jsx to Work with Correct Data

Instead of modifying objects in place, create new extensible copies with the Quantity property added using map:

const Files = ({ itemsInCartRef }) => { 
  // Create a new array with copied objects, adding Quantity
  const updatedItems = itemsInCartRef.current.map(item => {
    // Spread existing properties and add the new Quantity field
    return { ...item, Quantity: 1 };
  });

  // Update the ref with the new array (if you need to persist this change)
  itemsInCartRef.current = updatedItems;

  // Rest of your component logic...
};

Additional Notes

  • Why map? Spreading the original object into a new one creates an extensible copy, avoiding the "object is not extensible" error entirely.
  • Consider useState for Reactive State: If your component needs to re-render when cart items change, useRef won't trigger re-renders. Switching to useState is better for reactive management:
    const useItemsCartWithLocalStorage = (storageKey) => { 
      const [itemsInCart, setItemsInCart] = useState(() => 
        JSON.parse(localStorage.getItem(storageKey)) || []
      ); 
    
      useEffect(() => { 
        localStorage.setItem(storageKey, JSON.stringify(itemsInCart)); 
      }, [itemsInCart, storageKey]); 
    
      return [itemsInCart, setItemsInCart]; 
    }; 
    
    Use it in App.jsx:
    const [itemsInCart, setItemsInCart] = useItemsCartWithLocalStorage('itemsQuantityString'); 
    return <Files itemsInCart={itemsInCart} setItemsInCart={setItemsInCart} />; 
    
    And update in Files.jsx:
    const updatedItems = itemsInCart.map(item => ({ ...item, Quantity: 1 }));
    setItemsInCart(updatedItems);
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 03:27:49