0

I have a simple SEARCH_SUCCESS reducer that updates api response into state mapped by id like this:

[searchActionTypes.SEARCH_SUCCESS]: (state, { companies }) => {
    return update(state, { $merge: _.indexBy(companies, '_id') })
},

However, because my state is mapped by id, this is replacing any existing companies in state. This is a problem because I want to preserve extra data stored on existing companies in state.

I could just iterate through the companies and manually $merge state:

const newState = _.deepClone(state)
_.forEach(companies, company => newState[company._id] = state[company._id] ?
    update(state[company._id], { $merge: company }) : company
)
return newState

But this feels clunky. Is there a more elegant way to update nested state that will conditionally $merge or $set if keys are not present?

Clarkie
  • 7,490
  • 9
  • 39
  • 53
Robert Carter Mills
  • 793
  • 1
  • 9
  • 19
  • Related: https://stackoverflow.com/questions/32135779/updating-nested-data-in-redux-store . See also https://github.com/gaearon/normalizr . – Juho Vepsäläinen Mar 30 '16 at 08:17
  • The question you linked to is a generic question about updating redux state with an accepted answer that recommends using react-addons-update. I am already using this helper and link to it in my question. Abramov (creator of redux) also responds and recommends normalizer. My data is already normalized, hence why I am indexing records by ID. – Robert Carter Mills Mar 31 '16 at 03:02
  • To clarify, my question addresses a shortcoming of the update addon $merge operator, in that it only merges shallow, much like lodash assign. – Robert Carter Mills Mar 31 '16 at 03:04

1 Answers1

1

After some fiddling, I just abandoned the update $merge operator, because it is essentially equivalent to lodash assign and went with a combo of lodash cloneDeep and merge like this:

[dupeSearchActionTypes.SEARCH_SUCCESS]: (state, { companies }) => {
  // manually _.merge companies into state because react-addons-update $merge is shallow
  return _.merge(_.cloneDeep(state), _.indexBy(companies, '_id'))
},
Robert Carter Mills
  • 793
  • 1
  • 9
  • 19