3

I'm using redux with an api middleware similar to the one here, which normalizes response data and stores the results in the entity field of my state. So, if I made a request to the customers endpoint and it returned something like:

customers: [{
  id: 1,
  name: 'Bob',
  cards: [{id: 2, last4: '1234'}]
}]

My store would look like:

{
  entities: {
    cards: {2: {id: 2, last4: '1234'}}
    customers: {1: {id: 1, name: 'Bob'}}
  }
}

My question is, what is the best way to set up these associations again? Could this be done with a selector?

Danny Andrews
  • 456
  • 4
  • 10

3 Answers3

4

Yes, doing it in a selector sounds like a good plan. For simple cases, you can do this directly in components in mapStateToProps (which is pretty much a selector anyway). I have also seen some people writing code to denormalize the state using the normalizr schema lazily as componets access the properties which is something you might want to experiment with.

Dan Abramov
  • 264,556
  • 84
  • 409
  • 511
1

I found this library which makes it very easy to deal with related data in your redux store. redux-orm

Edgar
  • 6,022
  • 8
  • 33
  • 66
Danny Andrews
  • 456
  • 4
  • 10
0

In redux, only the reducer knows how to mutate the state. In your particular case, the reducer takes the customers payload and adds it to the state.

Example with one single customer as a payload:

const action = {
  customer: {
    id: 11,
    name: 'Joe',
    cards: [{id: 22, last4: '2345'}]
  }
};

const state = {
  entities: {
    cards: {2: {id: 2, last4: '1234'}},
    customers: {1: {id: 1, name: 'Bob'}}
  }
};

function reducerCustomer (state, action) {
  const cards = action.customer.cards.reduce((cards, card) => {
    cards[card.id] = card;
    return cards;
  }, {});

  const customers = {
    [action.customer.id]: {id: action.customer.id, name: action.customer.name}
  };

  return Object.assign({}, state, {
    entities: Object.assign({}, state.entities, {
      cards: Object.assign({}, state.entities.cards, cards),
      customers: Object.assign({}, state.entities.customers, customers)
    })
  });
}
danielepolencic
  • 4,905
  • 1
  • 26
  • 25