Estève
Estève

Reputation: 113

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:

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:

So, what is the best way to handle this?

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

Upvotes: 4

Views: 476

Answers (2)

alex3165
alex3165

Reputation: 195

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!

Upvotes: 2

MatBdry
MatBdry

Reputation: 21

In my opinion, a state should not contain the logic of the vues (like in the second method). It's just like a BDD when you pick up data (like an API). So the first method, with a selector to pick up the data depending of your vue is the best solution for me.

Upvotes: 1

Related Questions