Blog>
Snippets

Composing Selectors for Complex Data Structures

Provide a code example where multiple selectors are composed using createSelector to derive state that depends on different parts of the Redux store, like combining user information with their order history.
import { createSelector } from '@reduxjs/toolkit';

// Assuming our state shape has a 'users' slice and an 'orders' slice
const selectUsers = state => state.users;
const selectOrders = state => state.orders;

// A selector to get a specific user by ID
const selectUserById = (state, userId) => selectUsers(state).byId[userId];

// A selector to get orders for a specific user by user ID
const selectOrdersByUserId = createSelector(
  [selectOrders, selectUserById],
  (orders, user) => orders.allIds
    .map(id => orders.byId[id])
    .filter(order => order.userId === user.id)
);

// A memoized selector that combines user info with their order history
const selectUserDataWithOrders = createSelector(
  [selectUserById, selectOrdersByUserId],
  (user, orders) => ({ ...user, orders })
);
Composing selectors to derive a user's information combined with their order history. First, we define basic selectors for users and orders. Then, we create individual selectors to get a specific user by ID and to select a user's orders. Finally, we compose these selectors using createSelector to produce a combined object with user information and their associated orders, taking advantage of memoization for performance.