A memoized selector derives a value from state and recomputes only when the specific slices of state it reads change by reference. This is the core idea behind reselect, the standard memoization layer for Redux selectors: createSelector takes any number of cheap input selectors plus one result function, and it reruns the result function only when one of the input values changes — otherwise it hands back the previously cached result. createStructuredSelector composes a map of selectors into one selector that yields an object of their results, memoized the same way.
Build reselectSelectors, an object exposing createSelector and createStructuredSelector, plus a recomputations() counter on every selector so you can prove the cache is being reused.
type Selector = ((state: any, ...args: any[]) => any) & {
recomputations(): number;
};
const reselectSelectors: {
// (...inputSelectors, resultFn) -> a memoized selector
createSelector(...args: Function[]): Selector;
// { key: selector, ... } -> a selector returning { key: result, ... }
createStructuredSelector(map: Record<string, Function>): Selector;
};
const selectTotal = reselectSelectors.createSelector(
(state) => state.cart.items,
(items) => items.reduce((sum, item) => sum + item.price, 0),
);
const state = { cart: { items: [{ price: 10 }, { price: 5 }] } };
selectTotal(state); // 15 — runs the result function
selectTotal(state); // 15 — same items reference, returns the cached 15
selectTotal.recomputations(); // 1
const selectView = reselectSelectors.createStructuredSelector({
total: (state) => state.total,
user: (state) => state.user,
});
const r1 = selectView({ total: 42, user: { name: 'Ada' } });
// { total: 42, user: { name: 'Ada' } }
selectView.recomputations(); // 1
===. Immutable updates give a changed slice a new reference; an unchanged slice keeps its old one.recomputations() — returns how many times the result function ran, so a test can assert the cache was reused across calls.Unlock the solution & editor
Runnable editor + tests
Solve in the browser with instant Jest feedback.
Detailed solutions
Walkthroughs, edge cases, and complexity notes.
Multi-framework variants
React, Vue, Vanilla, Angular — same question, different stacks.