reactjs TypeError:“count”是只读的,该计数被分配一次,但第二次没有分配

wb1gzix0  于 2022-11-22  发布在  React
关注(0)|答案(2)|浏览(134)

当我第一次向购物车添加商品时,action.payload.count = 1;在我的切片中运行良好,但当我清空购物车(添加的商品被删除),然后再次添加该商品(相同的商品)时,控制台中出现以下错误,商品没有添加到购物车:
Uncaught TypeError: "count" is read-only addToCart CartSlice.js:13
当我添加新产品时,它没有任何错误(之前没有删除)。
为什么产品第一次添加正确,删除后没有再次添加?
cartSlice.js

export const CartSlice = createSlice({
    name: "cart",
    initialState: [],
    reducers: {
        addToCart(state, action){
            const existIndex = state.findIndex(item => item.shortName === action.payload.shortName);
            if(existIndex !== -1){
                state[existIndex].count += 1;
            }
            else{
                action.payload.count = 1;
                state.push(action.payload);
            }
        },
        clearCart(state, action){
            return state=[];
        }
    }
})

card.js

export const Card = ({product, showProductSlide}) => {
    const dispatch = useDispatch();
    const addToCart = () => {
        dispatch({type: "cart/addToCart", payload: product})
    }

    return(
        <div className="card item border-0 overflow-hidden">
            <div className="img-box">
                <img src={product.pic} className="card-img-top" alt="..." />
                <div className="triangle"></div>
            </div>
                <div className="card-body d-flex flex-column justify-content-between bg-secondary text-white">
                    <p className="card-text">{product.shortName}</p>
                    <p className="card-text text-end fw-bold">{product.price}</p>
                    <div className="d-flex justify-content-between">
                        <button className="btn btn-sm bg-transparent text-white" onClick={showProductSlide}><span className="q-mark me-1">?</span>Quick-view</button>
                        <button className="btn btn-sm bg-transparent btn-cart text-nowrap" onClick={addToCart}>Add to cart<div><span>+</span></div></button>
                    </div>
                </div>
        </div>
    )
}

cartList.js

export const CartList = ({showCart, cartProducts}) => {
    const dispatch = useDispatch();

    const totalPrices = () => {
        let total = 0;
        cartProducts.forEach(function (value){
            total += Number(value.price.replace(/[$]/, "")) * value.count;
        })
        return total.toFixed(2);
    }
    const clearCart = () => {
        dispatch({type: "cart/clearCart", payload: ""})
    }

    return(
        <div className={showCart ? "open-list" : "close-list"}>
            {cartProducts.length === 0 ?
                <span className="align-self-center">empty</span> :
                <>
                    <ul>
                        {cartProducts.map((item, index) => {
                                return(
                                    <li className="d-flex justify-content-between" key={index}>
                                        <span>{item.shortName}</span><span>{item.count}</span>
                                    </li>
                                )
                            }
                        )}
                    </ul>
                    <p className="total-price">Total Amounts: {totalPrices()}</p>
                    <button onClick={clearCart}>Cancel order</button>
                </>
            }
        </div>
    )
}

链接到输出:https://eloquent-kashata-a64506.netlify.app/
请执行以下操作:单击add to cart,然后清除购物车,并再次添加相同的产品。

z4iuyo4d

z4iuyo4d1#

实际上,改变减速器的action参数总是一个坏主意。在你的情况下,每次你这样做,你就改变了你的购物车产品。
我建议使用spread操作符并创建action payload state.push({ ...action.payload, count: 1 })的浅层副本。

vwkv1x7d

vwkv1x7d2#

无法直接改变操作负载。请将负载分配给变量并更改

else{
   const obj = {...action.payload}
   obj.count = 1;
   state.push(obj);
 }

相关问题