0
0
React Nativemobile~15 mins

Redux selectors in React Native - Deep Dive

Choose your learning style9 modes available
Overview - Redux selectors
What is it?
Redux selectors are functions that read specific pieces of data from the app's global state. They help components get only the data they need without knowing the full state structure. This makes the app easier to manage and faster to update.
Why it matters
Without selectors, components would have to dig through the entire state themselves, leading to repeated code and mistakes. Selectors keep data access clean and efficient, improving app performance and making debugging simpler. They also help when the state shape changes, reducing the work needed to update components.
Where it fits
Before learning selectors, you should understand Redux basics: actions, reducers, and the global state store. After selectors, you can learn about memoization and performance optimization in Redux, and how to use libraries like Reselect for advanced selectors.
Mental Model
Core Idea
Selectors are like smart windows that let components see only the exact part of the app's state they need.
Think of it like...
Imagine a big library (the Redux store) with many books (state data). A selector is like a librarian who quickly finds and hands you just the book or page you want, so you don't have to search the whole library yourself.
Redux Store (Global State)
┌─────────────────────────────┐
│                             │
│  { user: {...}, posts: {...} }  │
│                             │
└─────────────┬───────────────┘
              │
       Selector Functions
┌─────────────┴───────────────┐
│ getUser(state)              │
│ getPosts(state)             │
└─────────────┬───────────────┘
              │
       Components Use Data
┌─────────────┴───────────────┐
│ <UserProfile user={...} />  │
│ <PostList posts={...} />    │
└─────────────────────────────┘
Build-Up - 6 Steps
1
FoundationWhat is a Redux selector?
🤔
Concept: Selectors are simple functions that take the whole Redux state and return a part of it.
A selector looks like this: const getUser = (state) => state.user; It takes the state object and returns the user data inside it. This way, components can call getUser(state) to get user info without knowing the full state shape.
Result
You get a clean way to access user data from the state.
Understanding selectors as simple functions helps you see them as reusable tools to read state cleanly.
2
FoundationWhy use selectors instead of direct state access?
🤔
Concept: Selectors hide the state structure and keep data access consistent across the app.
Without selectors, components might do: const user = state.user; But if the state shape changes to state.auth.user, every component breaks. With selectors: const getUser = (state) => state.auth.user; Only the selector changes, components stay the same.
Result
Your app becomes easier to maintain and less error-prone when state changes.
Selectors act as a protective layer, preventing many bugs caused by state shape changes.
3
IntermediateCreating parameterized selectors
🤔Before reading on: do you think selectors can accept extra arguments besides state? Commit to yes or no.
Concept: Selectors can take extra parameters to return dynamic data based on input.
Example: const getPostById = (state, postId) => state.posts.find(post => post.id === postId); This selector returns the post matching the given id. Components can call getPostById(state, 5) to get post with id 5.
Result
Selectors become flexible tools that can return different data based on parameters.
Knowing selectors can accept parameters lets you write more dynamic and reusable data access functions.
4
IntermediateUsing memoized selectors for performance
🤔Before reading on: do you think selectors recalculate every time state changes, even if data is the same? Commit to yes or no.
Concept: Memoized selectors remember previous results and only recalculate when inputs change, improving performance.
Using the Reselect library: import { createSelector } from 'reselect'; const getPosts = (state) => state.posts; const getUserId = (state) => state.user.id; const getUserPosts = createSelector( [getPosts, getUserId], (posts, userId) => posts.filter(post => post.userId === userId) ); This selector recalculates only if posts or userId change.
Result
Your app avoids unnecessary recalculations and re-renders, making it faster.
Understanding memoization helps you write selectors that keep your app smooth and efficient.
5
AdvancedSelector composition for complex data
🤔Before reading on: do you think selectors can use other selectors inside them? Commit to yes or no.
Concept: Selectors can build on other selectors to create layered, readable data queries.
Example: const getUser = (state) => state.user; const getPosts = (state) => state.posts; const getUserPosts = createSelector( [getUser, getPosts], (user, posts) => posts.filter(post => post.userId === user.id) ); This breaks complex logic into small reusable pieces.
Result
Your selectors stay clean and easy to test, even for complex data needs.
Knowing how to compose selectors leads to better organized and maintainable code.
6
ExpertAvoiding common selector pitfalls
🤔Before reading on: do you think all selectors should always be memoized? Commit to yes or no.
Concept: Not all selectors benefit from memoization; misuse can cause bugs or wasted memory.
Memoizing selectors that return new objects or arrays every time can cause stale data or unnecessary renders. Example mistake: const getFilteredPosts = createSelector( [getPosts], (posts) => posts.filter(post => post.active) ); If posts change often, memoization may not help. Use memoization wisely, only for expensive or stable computations.
Result
You avoid performance traps and subtle bugs in your app.
Understanding when memoization helps or hurts is key to writing efficient Redux selectors.
Under the Hood
Selectors are just functions that receive the Redux state as input and return data. Memoized selectors use caching internally: they store the last inputs and output, and if inputs are unchanged, they return the cached output instead of recalculating. This reduces CPU work and prevents unnecessary UI updates.
Why designed this way?
Redux separates state management from UI to keep apps predictable. Selectors were designed to provide a clean, reusable way to access state without exposing its structure. Memoization was added later to solve performance issues when state updates frequently but data needed by components changes rarely.
┌───────────────┐
│ Redux State   │
│ (big object)  │
└───────┬───────┘
        │
        ▼
┌───────────────┐
│ Selector Func │
│ (input: state)│
│ (output: data)│
└───────┬───────┘
        │
        ▼
┌───────────────┐
│ Memoization   │
│ Cache inputs  │
│ Cache output  │
└───────┬───────┘
        │
        ▼
┌───────────────┐
│ Component UI  │
│ (receives data│
│  from selector)│
└───────────────┘
Myth Busters - 4 Common Misconceptions
Quick: do you think selectors automatically update components when state changes? Commit to yes or no.
Common Belief:Selectors automatically cause components to update whenever the state changes.
Tap to reveal reality
Reality:Selectors just return data; components update only if the data returned by selectors changes and React Redux detects it.
Why it matters:Assuming selectors trigger updates can lead to confusion when UI doesn't refresh as expected.
Quick: do you think all selectors must be memoized for best performance? Commit to yes or no.
Common Belief:All selectors should be memoized to improve app speed.
Tap to reveal reality
Reality:Memoization helps only for expensive or repeated calculations; simple selectors add unnecessary complexity if memoized.
Why it matters:Overusing memoization wastes memory and can cause bugs with stale data.
Quick: do you think selectors can modify the Redux state? Commit to yes or no.
Common Belief:Selectors can change or update the Redux state directly.
Tap to reveal reality
Reality:Selectors are pure functions that only read state; they never modify it.
Why it matters:Trying to change state in selectors breaks Redux rules and causes unpredictable bugs.
Quick: do you think selectors must always return new objects or arrays? Commit to yes or no.
Common Belief:Selectors should always create new objects or arrays to avoid mutation.
Tap to reveal reality
Reality:Selectors should return the same object if data hasn't changed to help React Redux detect changes efficiently.
Why it matters:Returning new objects unnecessarily causes extra renders and hurts performance.
Expert Zone
1
Selectors can be composed not only for data access but also for transforming data, enabling separation of concerns between raw state and UI-ready data.
2
Memoized selectors cache results per instance, so using them inside components with props requires creating selector instances to avoid shared cache bugs.
3
Selectors can be used outside React components, such as in middleware or thunks, to keep logic consistent and centralized.
When NOT to use
Avoid selectors when you need to write data back to the store; use actions and reducers instead. For very simple apps, direct state access might be enough without selectors. Also, avoid memoization for selectors that return new objects every time or when performance is not a concern.
Production Patterns
In real apps, selectors are organized in files by feature or domain. Developers use Reselect to create memoized selectors and compose them for complex queries. Selectors are tested independently to ensure correctness. They are also used in performance profiling to identify expensive computations.
Connections
Database Query Optimization
Similar pattern of caching and selective data retrieval
Understanding how selectors cache results helps grasp how databases optimize queries by caching and indexing to avoid full scans.
Functional Programming
Selectors are pure functions with no side effects
Knowing selectors are pure functions connects to functional programming principles, improving predictability and testability.
Human Attention Filtering
Selectors filter and focus on relevant information
Just like humans filter out distractions to focus on important details, selectors filter state to provide only needed data, improving efficiency.
Common Pitfalls
#1Selector returns new object every call causing unnecessary re-renders
Wrong approach:const getUserData = (state) => ({ ...state.user });
Correct approach:const getUserData = (state) => state.user;
Root cause:Creating new objects inside selectors breaks memoization and React Redux's shallow equality checks.
#2Using non-memoized selectors for expensive calculations
Wrong approach:const getFilteredPosts = (state) => state.posts.filter(p => p.active);
Correct approach:const getFilteredPosts = createSelector([getPosts], posts => posts.filter(p => p.active));
Root cause:Not memoizing expensive selectors causes repeated heavy computations on every state change.
#3Trying to modify state inside a selector
Wrong approach:const updateUser = (state) => { state.user.name = 'New'; return state.user; };
Correct approach:Selectors never modify state; use actions and reducers to update state instead.
Root cause:Misunderstanding selectors as state mutators breaks Redux's immutable state principle.
Key Takeaways
Redux selectors are pure functions that read and return specific parts of the global state, keeping data access clean and consistent.
Using selectors protects your app from bugs caused by state shape changes and reduces repeated code in components.
Memoized selectors improve performance by caching results and recalculating only when inputs change, but should be used wisely.
Selectors can be composed and parameterized to handle complex and dynamic data needs in a maintainable way.
Avoid common mistakes like returning new objects unnecessarily or trying to modify state inside selectors to keep your app efficient and bug-free.