Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Filtering Arrays in a Reducer - Redux

Following a React tutorial, I see this code in a reducer to remove a message from an array using its ID:

enter image description here Wouldn't this be better written as:

else if (action.type === 'DELETE_MESSAGE') { return { messages: [ ...state.messages.filter(m => m.id === action.id) ], }; };

I thought for a second that filter might modify state and return the same array but according to MDN it creates a new array.

Am I safe, and is my implementation correct?

like image 690
softcode Avatar asked Dec 22 '16 06:12

softcode


1 Answers

Yes. It would actually be a very clean solution. The trick is that, in Array#filter, every element of an array is applied with a function that accepts more than one argument. Such a function, when returns a boolean value, is called predicate. In case of Array#filter (and in fact, some other methods of Array.prototype), the second argument is index of the element in source array.

So, given that you know the index, it's simply

(state, action) => ({
  ...state,
  messages: state.messages.filter((item, index) => index !== action.index)
})

However, you don't know the index. Instead, you have a value of id property. In this case, you're right, you simply need to filter the source array against this id to only put elements that have value of id that is not equal to target id:

(state, action) => ({
  ...state,
  messages: state.messages.filter(item => item.id !== action.id)
})

Take a note: no need to spread state.messages and put them back into a new array. Array#filter doesn't mutate the source array, which is nice.

So, it's !== instead of ===. You were close.

like image 94
rishat Avatar answered Sep 18 '22 23:09

rishat