Reputation: 3166
So I was working with redux and reactjs, although the question is not related:
I have this collection
const items = [
{id: 0, name: 'one'},
{id: 1, name: 'two'},
{id: 2, name: 'three'}
]
const itemsWithTheFlag = [
{id: 0, flag: false},
{id: 1, flag: true},
{id: 2, flag: false},
]
Then my initial state is:
{
items: items
}
Now I wonder how can I perform find and update in items
array,
One of my functions is mocking an async
request and receiving item from itemsWithTheFlag
export function fetch(id) {
const desiredItem = find(itemsWithTheFlag, (item) => (item.id === id))
return (dispatch, getState) => {
return new Promise((resolve) => {
setTimeout(() => {
dispatch(receiveItem(desiredItem))
resolve()
}, 100)
})
}
}
Now I want help to update the state, with updated merged
values, I receive from fetch
and the initial state items
[RECEIVE_ITEM]: (state, action) => {
return Object.assign({}, state, {
// how ??
})
}
I want to keep the immutability of course, using lodash is fine as well
Upvotes: 1
Views: 170
Reputation: 1364
You need to return a new array, with just that item swapped out. This way has the benefit of not going over all of state.items
, which is a bit more performant on large arrays (but the solution in this instance does use lodash)
const index = _.findIndex(state.items, { id: action.newItem.id });
return {
...state,
items: [
...state.items.slice(0, index),
{ ...state.items[index], ...action.newItem },
...state.items.slice(index + 1)
]
};
Upvotes: 0
Reputation: 45121
You need to recreate entire array and patch item with corresponding id.
return Object.assign({}, state, {
items: state.items.map(
item => (
item.id === action.desiredItem.id
? Object.assign({}, item, desiredItem)
: item)
)
})
Upvotes: 1