Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why Immer didn't return me a new state even if I modified the draft?

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.

like image 783
Daniel Chan Avatar asked Aug 01 '20 02:08

Daniel Chan


1 Answers

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

like image 115
Rodrigo Amaral Avatar answered Nov 15 '22 03:11

Rodrigo Amaral