Handling many entities on Redux without repetition

371 views Asked by At

I'm creating a React + Redux app, but I'm unsure on how to go about this reducer.

Following the example on real-word I'm using the following code to store my entities.

// Updates an entity cache in response to any action with response.entities.

const entities = (state = initialState, action) => {
  if (action.response && action.response.entities) {
    return merge({}, state, action.response.entities)
  }

  return state
}

The question is: How can I handle an update on a nested entity? Everything is already normalized, so it would be a matter of getting the keys and updating them, but I can't figure out how.

I could use the example from the docs, but it only shows how to solve a simple case, where there are only 2 entities so I can have one reducer for each. I have 8 (and possibly more) entities and it would be a lot of work to create one reducer for each, with every action for fetching and receiving, but maybe that's the approach I should take?

2

There are 2 answers

1
Harkirat Saluja On

For handling nested entities I feel immutablejs is a really good option. Its really easy to update nested objects and arrays. The syntax as well as usage is really simple.

I have already answered a similar question.Adding a link in the comments

3
jpdelatorre On

One option is to add an action type handler inside that reducer function

const entities = (state = initialState, action) => {
   if (action.type === 'UPDATE_ENTITY') {
      return {
          ...state,
          [action.payload.entity]: {
              ...state[action.payload.entity],
              [action.payload.id]: {
                  ...state[action.payload.entity][id],
                  [action.payload.field]: action.payload.value
              }
          }
      }
   }

   if (action.response && action.response.entities) {
      return merge({}, state, action.response.entities)
   }

   return state
}

Your actions might look something like

const updateEntity = (entity, id, field, value) => ({
    type: 'UPDATE_ENTITY',
    payload: {entity, id, field, value}
})

This is just one way. There are a lot of other approaches depending on your use case.