Redux & Redux Toolkit
/Advanced
Selector Performance
Definition
The study of how poorly written selectors can destroy React performance by forcing components to re-render even when the Redux state hasn't meaningfully changed.
Explain Like I'm New
`useSelector` uses strict equality (`===`) to check if data changed. If your selector returns a literal object `{}` or uses `.filter()`, it creates a NEW memory address every single time it runs. `useSelector` sees a new memory address, thinks the data changed, and forces your component to re-render, creating a devastating performance loop.
Real World Example
A component that uses `useSelector(state => state.items.filter(i => i.active))`. Every time ANY action is dispatched in the entire app, this component will needlessly re-render.
Common Use Cases
- •Fixing sluggish React apps
- •Profiling Redux DevTools
Interactive Example
// ❌ DISASTER: .map() creates a new array every time ANY state changes! // The component will re-render constantly, killing performance. const activeIds = useSelector(state => state.todos.filter(t => t.active).map(t => t.id) ); // ✅ FIX 1: Use a memoized selector (createSelector) const activeIds = useSelector(selectActiveTodoIds); // ✅ FIX 2: Use the shallowEqual comparison function import { useSelector, shallowEqual } from 'react-redux'; const activeIds = useSelector( state => state.todos.filter(t => t.active).map(t => t.id), shallowEqual // Tells Redux: 'Only re-render if the actual items inside the array changed' );
Interview Questions
basic
- Why is returning an object literal like `useSelector(state => { data: state.data })` a terrible idea?
intermediate
- How does RTK's `shallowEqual` utility help with selector performance?