Lee
Lee

Reputation: 5936

Reselect selectors structure

i have the following example structure..

userId: {
  savedEvents: {
     eventId: true,
     eventId: true,
     eventId: true,
  },
  organisedEvents: {
     eventId: true,
     eventId: true,
     eventId: true,
  },
  attendingEvents: {
     eventId: true,
     eventId: true,
     eventId: true,
  }
}

I am using reselects createSelector method to try and chain selectors for memory optimisations and re-use of business logic..

For example :-

userOrganisedEventsSelector

Returns a list of organised event ids.

activeUserOrganisedEventsSelector

Uses the output of userOrganisedEventsSelector with a set of filters have been applied

sortedActiveUserOrganisedEventsSelector 

Sorts the output of activeUserOrganisedEventsSelector

The three above methods accept a prop object containing userId, from which it can then determine the organised event.

The problem :-

  1. I want the same functionality for all three event types (savedEvents, organisedEvents and attendingEvents)

  2. In some scenarios i would like the userId to be provided by props, other times i need to use a userId from state.

I am looking for help or advise on how to achieve this, without creating 30 odd functions, while keeping the benefits of memorising via reselect.

Upvotes: 1

Views: 1241

Answers (1)

Andrea Carraro
Andrea Carraro

Reputation: 10429

I'd suggest you to give re-reselect a try. It's a tiny reselect wrapper I wrote when I found my self writing almost identical selectors in a scenario similar to yours.

It will allow you to not repeat selectors code and to better manage selectors caching when passing different params (eg, your userID).

Here a few line of pseudocode, just you get you on the right track:

import createSelector from 'reselect';
import createCachedSelector from 're-reselect';

// Normal reselect selector:
// getUserEvents(state, userId)
const getUserEvents = createSelector(
  state => state.events
  (state, userId) => userId,            // Get user from state if userId not provided
  (events, userId) => events[userId],   // Return user's events
);

// Cached re-reselect selector (cached by eventType):
// getUserEventsOfType(state, userId, eventType = 'ALL')
const getUserEventsOfType = createCachedSelector(
  getUserEvents,                        // Get events from getUserEvents
  (state, userId, eventType = 'ALL') => eventType,
  (userEvents, eventType) => userEvents[eventType]  // Just pseudo code!
)(
  // Keep memoization when calling selector with different eventType
  (state, userId, eventType = 'ALL') => eventType,
);

Upvotes: 3

Related Questions