Reputation: 325
Can't figure out how to properly insert an element into an array, that's inside an object, that's inside an array. Here's an example of my default data for structure:
const defaultState = {
myinbox: [
{
owner: 'John Lennon',
owner_id: 1,
read: true,
messages: [
{
_id: 1,
text: 'When will you be home?',
createdAt: new Date(Date.UTC(2017, 10, 11, 11, 20, 0)),
user: {
_id: 1,
name: 'John Lennon'
}
}
...
I want to add another message when an inbound message comes in. This is what the snippet from my reducer looks like:
const inboxReducer = (state = defaultState, action) => {
switch (action.type) {
case 'ADD_INBOUND_MESSAGE':
return {
...state,
myinbox: [
state.myinbox[action.payload.index]: {
...state.myinbox[action.payload.index],
messages: [
...state.myinbox[action.payload.index].messages,
action.payload.msg
]
}
...state.myinbox,
]
}
default:
return state
}
}
The index of the parent "owner" is passed as the index inside the payload, and the new message is msg in the payload.
I can't figure out how to write this reducer without mutating the original state.
Upvotes: 0
Views: 1063
Reputation: 1
This can be done with Immer
const { index, msg } = action.payload;
return produce(state, (draftState) => {
draftState.myinbox[index].messages.push(msg);
});
Upvotes: 0
Reputation: 1598
You're mutating the original state when you set myinbox
using state.myinbox[action.payload.index]:
.
Looks like you're trying to set the state for the index using computed property keys. The syntax for that would be:
myinbox: [
[action.payload.index]: {
...state.myinbox[action.payload.index],
messages: [
...state.myinbox[action.payload.index].messages,
action.payload.msg
]
}
...state.myinbox,
]
Upvotes: 2