DigitalDisaster
DigitalDisaster

Reputation: 517

Spread operator overwriting elements in new object instead of combining

I'm getting data from my API, and passing it through normalizr before dumping it into redux. When I get people data from the API the reducer should append them to the people store. Right now my reducer is overwriting all existing data in the store.

The reducer:

export default function reducer(state={
    people: {
        entities : {
          people: {
            0 : {
              name : ''
            }
          }
        },
        result : [0,]
    }
  }, action) {
  switch (action.type) {
    case "GET_PEOPLE": {
      const newpPeople = {...state.people, ...action.payload };
      console.log(state.people)
      console.log(action.payload)
      console.log(newpPeople)
      return {...state, people : newpPeople};
    }
    default :
      return state
  }
}

This first console log is the state after the reducer has been used once. it has the initial set of people that i've saved to the store:

{ 
    entities: { 
                people : { 
                          1 : { id: 1, name: "jim" },
                          2 : { id: 2, name: "billy" }
                         }
              },
    result : [ 1, 2 ]
}

The second console log will be the payload of new people to be added:

{ 
    entities: { 
                people : { 
                          7 : { id: 7, name: "sally" },
                          8 : { id: 8, name: "ana" }
                         }
              },
    result : [ 7, 8 ]
}

Then the third console log should be the two states combined? But it just repeats the last one with sally and ana, and overwrites everything else.

Upvotes: 4

Views: 9522

Answers (1)

Rafael Z.
Rafael Z.

Reputation: 1162

That's because spread will not combine the objects recursively.

Take a look at this simple example where it works as you expected:

const state = { 
        entities: { 
                    people : { 
                              1 : { id: 1, name: "jim" },
                              2 : { id: 2, name: "billy" }
                             }
                  },
        result : [ 1, 2 ]
    }
    
    const payload = { 
        entities: { 
                    people : { 
                              7 : { id: 7, name: "sally" },
                              8 : { id: 8, name: "ana" }
                             }
                  },
        result : [ 7, 8 ]
    }
    
    const new_state = { 
        entities: { 
                    people : { 
                              ...state.entities.people,...payload.entities.people
                             }
                  },
        result : [...state.result,...payload.result]
    }
    
    console.log(new_state)

Upvotes: 5

Related Questions