Replace/Change Redux state array with other array using immer

2k Views Asked by At

I am using immer to manage my redux state. It has an item which is an array of customers. There is a delete button on my website and on the delete button, I want to delete the item from the array in the list of customers in my state. In this example, I want to delete Id 100

Redux State

customers : [{Id: "100", Name: "John"},{Id: "200", Name: "Mark"}],
address: null,
randomStuff [{}]

Code

customerIdToBeDeleted = 100

const newCustomers = produce(customers, (draft) => {
      const newCustomers = draft.filter((x) => x.Id !== customerIdToBeDeleted );
      draft = newCustomers ;
    }); 

This does not work. It says cannot reassign the parameter draft. How can I remove one Id from the array and store that in the state?

1

There are 1 best solutions below

0
On BEST ANSWER

In a normal reducer you would return a new array from the old array, which is what you are doing here. But Immer is based around mutation. Rather than reassigning, what you want to do is alter the contents of the array variable draft. We do this by calling mutating methods like push(), pop(), and in this case splice().

There's an example in the Immer docs on update patterns which is applicable here.

// delete by id
const deletedTodosArray = produce(todosArray, draft => {
    const index = draft.findIndex(todo => todo.id === "id1")
    if (index !== -1) draft.splice(index, 1)
})

In your case it is:

const customerIdToBeDeleted = "100"; // since your customer ids are strings

const newCustomers = produce(customers, (draft) => {
  const index = draft.findIndex(x => x.Id === customerIdToBeDeleted);
  if (index !== -1) draft.splice(index, 1);
})

Edit: I believe it is also ok to return the new value. You just can't assign it to draft.

const newCustomers = produce(customers, (draft) => {
  return draft.filter(x => x.Id !== customerIdToBeDeleted );
});