最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Filtering Arrays in a Reducer - Redux - Stack Overflow

programmeradmin3浏览0评论

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

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?

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

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?

Share Improve this question edited Dec 22, 2016 at 6:50 softcode asked Dec 22, 2016 at 6:16 softcodesoftcode 4,64812 gold badges44 silver badges69 bronze badges 3
  • It appears the spread operator concats both arrays. see repl.it/EvXg/1 @Rajesh – softcode Commented Dec 22, 2016 at 6:38
  • I wonder if there are performance reasons. Could the slice method be faster with a large array? – Scimonster Commented Dec 22, 2016 at 7:59
  • @Scimonster That's what I was thinking. I don't understand their approach, it seems deceivingly inefficient. – softcode Commented Dec 22, 2016 at 16:49
Add a comment  | 

1 Answer 1

Reset to default 17

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.

发布评论

评论列表(0)

  1. 暂无评论