4

I'm trying to modify the field quantity of obj meal in the array orderedList. This is the error:


TypeError: Cannot assign to read only property 'quantity' of object '#'


How I can change this state.


Please help.Please help.Please help.Please help.Please help.Please help.Please help. Please help.Please help.Please help.Please help.Please help.Please help.Please help.


import {createSlice} from "@reduxjs/toolkit";

const menuList = [
    {
        id: 'm1',
        name: 'Sushi',
        description: 'Finest fish and veggies',
        price: 22.99,
        quantity: 0
    },
    {
        id: 'm2',
        name: 'Schnitzel',
        description: 'A german specialty!',
        price: 16.5,
        quantity: 0
    },
    {
        id: 'm3',
        name: 'Barbecue Burger',
        description: 'American, raw, meaty',
        price: 12.99,
        quantity: 0
    },
    {
        id: 'm4',
        name: 'Green Bowl',
        description: 'Healthy...and green...',
        price: 18.99,
        quantity: 0
    },
];

const initialStateMeals = {
    menuList,
    orderedList: [],
    numberOfOrderedMeals: 0,
    showCart: false,
    totalAmount: 0
}

const counterSlice = createSlice({
    name: 'meals',
    initialState: initialStateMeals,
    reducers: {
        add(state, action) {
            state.numberOfOrderedMeals += +action.payload.input;
            let totalAmountTemp = state.totalAmount + action.payload.meal.price * action.payload.input;
            state.totalAmount = +totalAmountTemp.toFixed(2);

            let mealIsInList = state.orderedList.filter(meal => meal.id === action.payload.meal.id).length > 0;

            if (!mealIsInList) {
                state.orderedList.push(action.payload.meal);
                state.orderedList.filter(meal => meal.id === action.payload.meal.id)[0].quantity = 1;
                //on this line I have this error
                //TypeError: Cannot assign to read only property 'quantity' of object '#<Object>'
            } else {
            }
        },
        remove(state, action) {
            state.numberOfOrderedMeals -= +action.payload.input;
        }
        ,
        closeCart(state) {
            state.showCart = false;
        }
        ,
        showCart(state) {
            state.showCart = true;
        }
    }
});

export default counterSlice.reducer;
export const mealsAction = counterSlice.actions;

My guess here is that redux-toolkit is protecting you from mutating the action's payload object as this mutation could leak out into any other reducer listening for the same action.

Instead of pushing into the array, and then iterating it again just to find the element you pushed, which will be the last element in the array, BTW, you could just create a new object with the properties you want and push this into the array instead.

if (!mealIsInList) {
  state.orderedList.push({
    ...action.payload.meal,
    quantity: 1,
  });
}
4

1 回答 1

1

我的猜测是 redux-toolkit 正在保护你不改变动作的payload对象,因为这种突变可能会泄漏到任何其他监听相同动作的减速器中。

而不是推入数组,然后再次迭代它只是为了找到你 push 的元素,这将是数组中的最后一个元素,顺便说一句,你可以创建一个具有所需属性的新对象并将其推入数组反而。

if (!mealIsInList) {
  state.orderedList.push({
    ...action.payload.meal,
    quantity: 1,
  });
}
于 2021-09-07T23:37:14.627 回答