Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to organize partial entities in normalized redux store?

For the needs of my project I have to chose between two way to organize entities in reducer.

The case is that the API only returns the data needed by the different views for the same object (a car in this example).

So the first way is to go with a normalized state storing non standardized data but using selectors to avoid object having data the view does not need

const store = {
  entities: {
    car: {
      1: {
        id: 1,
        name: "SuperCar",
        date: "1992",
        constuctor: "Super Constructor",
      },
      2: {
        id: 2,
        name: "BasicCar",
        date: "1987",
        picture: "...",
        constuctor: "Amazing Constructor",
        possessors: [3,45,34]
      }
    },
    possessors: {
      /// ...
    }
  },
  requestResult: {
    car_for_list: [2],
    car_for_home: [1, 2],
  }
}
const getCarsForHome = state => state.requestResult.car_for_home.map(id => state.entities.car[id])

The pitfalls are:

  • I don't know the consistency of the data by entity

The second way I see is to consider have a master entity (like a parent class) and to use selectors to get the correct data for the view. The master entity owns all the shared properties for all the views and specific entities owns others.

const store = {
  entities: {
    car: {
      1: {
        id: 1,
        name: "SuperCar",
        date: "1992",
        car_for_home: 1, // key to get the details for home view,
      },
      2: {
        id: 2,
        name: "BasicCar",
        date: "1987",
        car_for_home: 2, // key to get the details for home view,
        car_for_list: 2 // key to get the details for list view
      }
    },
    car_for_home: {
      1: {
        id: 1,
        constuctor: "Super Constructor",
      },
      2: {
        id: 2,
        constuctor: "Amazing Constructor",
      }
    },
    car_for_list: {
      2: {
        id: 2,
        picture: "...",
        possessors: [3,45,34]
      }
    },
    possessors: {
      /// ...
    }
  }
}
//Selector
const getCarsForHome = state => Object.values(state.entities.car_for_home).map( car => ({ ...state.entities.car[car.id], ...car }))

The pitfalls are:

  • It's hard to maintain the store in case of update or delete
  • If a view needs to display a new property, I may have to modify my store (eg: car_for_list now need the constructor so I have to store it in the main car)

So, what is the best way to handle this?

So you know, the project is big, production and will scale.

like image 577
Estève Avatar asked Oct 15 '25 18:10

Estève


1 Answers

I would keep the state as simple as possible and keep it like in the first example. Typescript can help with the consistency of the data, this would be the interface you could use to help with your first example:

Interface Car {
id: string;
name: string;
constructor: string;
pictures?: string[];
processor?: number[];
}

Keep the properties you might not have optional then unwrap when necessary so you handle all the cases (undefined or set) everywhere in your app. The challenge here is to keep your types rights in your selectors but typescript has very good type inferences and if you use reselect the types for this library are good!

like image 148
alex3165 Avatar answered Oct 17 '25 10:10

alex3165