Spread operator overwriting elements in new object instead of combining

9.3k views Asked by At

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.

1

There are 1 answers

4
Rafael Z. On BEST ANSWER

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)