intermediate

Selectors

Encapsulate reads, derive view models, and memoize expensive projections when inputs are stable.

Selectors encapsulate reads and derived projections from the store. Simple selectors read a slice; memoized selectors (reselect) recompute only when input slices change reference or value.

					import { createSelector } from '@reduxjs/toolkit';

const selectTodos = (state) => state.todos;
const selectActiveTodos = createSelector([selectTodos], (todos) =>
  todos.filter((t) => !t.done),
);
				

Colocate selectors with slices. View components should not know store shape — they call `selectCartTotal(state)` or `useSelector(selectCartTotal)`.

The trade-off is encapsulated reads and memoization versus memory for caches and complexity when inputs churn.

On interviews: when memoization helps versus adds overhead; how normalization shifts work to selectors.

Common pitfalls: inline arrow functions in `useSelector` creating new references every render, selectors that mutate state, and deriving in components instead of shared selectors.

Checklist:

  • Encapsulate shape behind selectors.
  • Memoize expensive joins and filters.
  • Stable selector references to useSelector.
  • Test selectors as pure functions.