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.