Redux: Handling complex store relationships

Created on 2 Aug 2015  路  2Comments  路  Source: reduxjs/redux

This is more database related than just Redux but here goes...

Let's say Redux has a store that looks like this:

{
  meals: {
    collection: [{
      name: 'Turkey',
      id: 1
    },{
      name: 'Fish',
      id: 2
    }],

    selectedMeals: [1]
  }
}

My interface has the ability to delete a meal, here's the relevant reducer function:

function deleteMeal(state, action) {
  const meals = state.collection.filter((meal) => {
    return meal.id !== action.payload
  })

  return {
    ...state,
    collection: meals,
  }
}

There is a bug here. I must also remove the id from the selectedMeal array too.

function deleteMeal(state, action) {
  const meals = state.collection.filter((meal) => {
    return meal.id !== action.payload
  })

  const selectedMealIds = state.selectedMealIds.filter((id) => {
    return id !== action.payload
  })

  return {
    collection: meals,
    selectedMealIds
  }
}

The interesting thing is my interface doesn't bork but I _know_ the store is not 'truthful'. I must manually remove the id reference from the store. That makes sense but I am wondering if there is a better way?

Taking a look at this Baobab article provides some interesting thoughts.

question

Most helpful comment

Deleting is always tricky because there is no first class notion of a schema. We don't know which parts of state are actually references to IDs and need to be updated.

I see three solutions:

  1. For entities which are rarely deleted, reload the page. It's not too bad if it happens rarely (e.g. selecting something like a Facebook group or a blog post leading to refresh is normal IMO, you don't do that every day).
  2. For entities that may often get deleted, you may consider a status field. For example, deleting may set isDeleted on the model. This way it's still there, but it's up to the UI to filter deleted items out.
  3. You can make schema a first class concept, just like it's first class in normalizr. If you have a schema, you can write a reducer factory that creates reducers adhering to this schema. These reducers will know when to remove IDs from foreign key fields because they know what the schema looks like.

All 2 comments

Deleting is always tricky because there is no first class notion of a schema. We don't know which parts of state are actually references to IDs and need to be updated.

I see three solutions:

  1. For entities which are rarely deleted, reload the page. It's not too bad if it happens rarely (e.g. selecting something like a Facebook group or a blog post leading to refresh is normal IMO, you don't do that every day).
  2. For entities that may often get deleted, you may consider a status field. For example, deleting may set isDeleted on the model. This way it's still there, but it's up to the UI to filter deleted items out.
  3. You can make schema a first class concept, just like it's first class in normalizr. If you have a schema, you can write a reducer factory that creates reducers adhering to this schema. These reducers will know when to remove IDs from foreign key fields because they know what the schema looks like.

Thanks for the advice. I think the isDeleted field is a pragmatic solution suitable for my scenario. I'm not very familiar with normalizr but the concept looks appealing, especially for a larger more relationship heavy data set. I'll have to take a closer look.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ilearnio picture ilearnio  路  3Comments

vslinko picture vslinko  路  3Comments

cloudfroster picture cloudfroster  路  3Comments

jbri7357 picture jbri7357  路  3Comments

captbaritone picture captbaritone  路  3Comments