When to Avoid Redux Selectors in React
Redux selectors are widely used in React applications to extract and compute state efficiently. However, they are not always the optimal choice for every state-access scenario. This article explores the specific situations where you should avoid using Redux selectors, such as when dealing with simple state extractions, highly dynamic inputs that break memoization, and localized component states where standard React hooks or context are more appropriate.
Simple and Uncomputed State Extraction
If you only need to retrieve a top-level property from your Redux
store without any transformation, writing a custom selector adds
unnecessary boilerplate. For example, accessing a simple value like
state.auth.isLoggedIn directly inside the
useSelector hook is cleaner and more readable than
creating, importing, and maintaining a dedicated selector file. Reserve
selectors for complex queries or when data needs to be filtered,
combined, or transformed.
Highly Dynamic Inputs That Bust Memoization
Memoized selectors (created with libraries like Reselect) rely on
caching inputs to avoid expensive recalculations. If you pass rapidly
changing arguments—such as a unique ID in a large, fast-rendering
list—the selector’s cache will constantly clear and recalculate. This
“cache busting” negates all performance benefits of memoization and adds
computational overhead. In these cases, it is more efficient to select
the raw data array and perform the lookup or filtering directly inside
the component using React’s native useMemo hook.
Component-Local and Transient UI State
You should avoid using Redux selectors for data that does not need to
be shared globally. Managing transient UI states—such as whether a
dropdown is open, a form input value before submission, or a modal’s
visibility—inside Redux leads to bloated global state and unnecessary
selector maintenance. This type of state is best handled using React’s
local useState or useReducer hooks, keeping
your Redux store clean and focused solely on global application
data.
Trivial Computations
If a calculation is computationally cheap, creating a selector is
often overkill. Basic operations like checking if an array is empty
(state.items.length === 0) or converting a string to
lowercase can be done directly during the render phase of your
component. Overusing selectors for trivial logic clutter the codebase
without providing any measurable performance improvements.