Reputation: 433
I don't know why even I have modified the draft, immer didn't provide me with a new state, but the old state instance with modified content.
import CartItem from "../../models/cart-item";
import * as actions from "../actions/actionTypes";
import produce from "immer"
const initialState = [];
const reducer = (state=initialState, action) => {
switch (action.type) {
case actions.ADD_TO_CART:
const {id, title, price} = action.product;
const itemIndexInCart = state.findIndex(item => item.id === id);
const nextState = produce(state, draftState => {
if (itemIndexInCart === -1) {
draftState.push(new CartItem(id, 1, price, title, price));
} else {
draftState[itemIndexInCart]['quantity']++;
draftState[itemIndexInCart]['sum'] += price;
}
});
console.log(state === nextState);
return nextState;
default:
return state;
}
};
export default reducer;
It is working when new item is pushing into the array, but it is not working as expected when I want to modify the quantity and sum of the array item. The log show me it's the same object under that circumstances.
Upvotes: 6
Views: 3465
Reputation: 67469
Note that you should never put non-serializable values like class instances into the Redux store.
In addition, you should be using our official Redux Toolkit package, which will let you simplify your existing Redux logic. For example, this reducer could be written as:
const cartSlice = createSlice({
name: "cart",
initialState: [],
reducers: {
addToCart(state, action) {
const {id, title, price} = action.payload;
const item = state.find(item => item.id === id);
if(item) {
item.quantity++;
item.sum += price;
} else {
state.push({id, price, title, quantity: 1});
}
}
}
})
Upvotes: 1
Reputation: 1382
The trick is to make your class immerable, according to the docs. Notice that console.logging a draft might print "null", even though this object is not null.
import {immerable} from "immer"
class Foo {
[immerable] = true // Option 1
constructor() {
this[immerable] = true // Option 2
}
}
Foo[immerable] = true // Option 3
Working demo: https://codesandbox.io/s/blissful-resonance-v6v9b?file=/src/App.js
Upvotes: 2