Bird
Raised Fist0
React Nativemobile~20 mins

Redux selectors in React Native - Mini App: Build & Ship

Choose your learning style10 modes available
Build: Todo List with Redux Selectors
This screen shows a list of todo items stored in Redux state. It uses selectors to get filtered todos and the count of completed todos.
Target UI
-------------------------
| Todo List             |
|-----------------------|
| [ ] Buy groceries     |
| [x] Walk the dog      |
| [ ] Read a book       |
|-----------------------|
| Completed: 1          |
-------------------------
Use Redux selectors to get all todos from state
Use a selector to get only completed todos
Display the list of todos with a checkbox for completed status
Show the count of completed todos below the list
Starter Code
React Native
import React from 'react';
import { View, Text, FlatList, Switch, StyleSheet } from 'react-native';
import { useSelector, useDispatch } from 'react-redux';

// TODO: Define selectors here

export default function TodoListScreen() {
  const dispatch = useDispatch();

  // TODO: Use selectors to get todos and completed count

  const toggleTodo = (id) => {
    // TODO: Dispatch action to toggle todo completed status
  };

  return (
    <View style={styles.container}>
      <Text style={styles.title}>Todo List</Text>
      <FlatList
        data={[]}
        keyExtractor={(item) => item.id.toString()}
        renderItem={({ item }) => (
          <View style={styles.todoItem}>
            <Switch
              value={false}
              onValueChange={() => toggleTodo(item.id)}
            />
            <Text style={styles.todoText}>{item.text}</Text>
          </View>
        )}
      />
      <Text style={styles.completedCount}>Completed: 0</Text>
    </View>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1, padding: 20, backgroundColor: '#fff' },
  title: { fontSize: 24, fontWeight: 'bold', marginBottom: 10 },
  todoItem: { flexDirection: 'row', alignItems: 'center', marginBottom: 10 },
  todoText: { marginLeft: 10, fontSize: 18 },
  completedCount: { marginTop: 20, fontSize: 18, fontWeight: 'bold' },
});
Task 1
Task 2
Task 3
Task 4
Task 5
Task 6
Solution
React Native
import React from 'react';
import { View, Text, FlatList, Switch, StyleSheet } from 'react-native';
import { useSelector, useDispatch } from 'react-redux';

// Selector to get all todos
const selectTodos = (state) => state.todos;

// Selector to get completed todos
const selectCompletedTodos = (state) => state.todos.filter(todo => todo.completed);

export default function TodoListScreen() {
  const dispatch = useDispatch();

  const todos = useSelector(selectTodos);
  const completedTodos = useSelector(selectCompletedTodos);

  const toggleTodo = (id) => {
    dispatch({ type: 'TOGGLE_TODO', payload: id });
  };

  return (
    <View style={styles.container}>
      <Text style={styles.title}>Todo List</Text>
      <FlatList
        data={todos}
        keyExtractor={(item) => item.id.toString()}
        renderItem={({ item }) => (
          <View style={styles.todoItem}>
            <Switch
              value={item.completed}
              onValueChange={() => toggleTodo(item.id)}
              accessibilityLabel={`Toggle todo ${item.text}`}
            />
            <Text style={styles.todoText}>{item.text}</Text>
          </View>
        )}
      />
      <Text style={styles.completedCount}>Completed: {completedTodos.length}</Text>
    </View>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1, padding: 20, backgroundColor: '#fff' },
  title: { fontSize: 24, fontWeight: 'bold', marginBottom: 10 },
  todoItem: { flexDirection: 'row', alignItems: 'center', marginBottom: 10 },
  todoText: { marginLeft: 10, fontSize: 18 },
  completedCount: { marginTop: 20, fontSize: 18, fontWeight: 'bold' },
});

We created two selectors: one to get all todos, and one to get only completed todos. This keeps our component clean and focused on UI.

We use useSelector to get the todos and completed todos count from Redux state.

The FlatList shows all todos with a switch to toggle completion. When toggled, it dispatches an action to update the store.

This approach separates data selection logic from UI, making code easier to maintain and test.

Final Result
Completed Screen
-------------------------
| Todo List             |
|-----------------------|
| [ ] Buy groceries     |
| [x] Walk the dog      |
| [ ] Read a book       |
|-----------------------|
| Completed: 1          |
-------------------------
User can toggle the switch next to each todo to mark it completed or not.
Completed count updates automatically when toggles change.
Stretch Goal
Add a selector to get only incomplete todos and display their count below the completed count.
💡 Hint
Create a selector filtering todos where completed is false, then use useSelector to get its length.

Practice

(1/5)
1. What is the main purpose of a Redux selector in a React Native app?
easy
A. To create UI components
B. To extract specific data from the Redux store state
C. To define the initial state of the store
D. To dispatch actions to update the store

Solution

  1. Step 1: Understand Redux store role

    The Redux store holds the entire app state in one place.
  2. Step 2: Role of selectors

    Selectors are functions that pick specific parts of that state for use in components.
  3. Final Answer:

    To extract specific data from the Redux store state -> Option B
  4. Quick Check:

    Selector = extract data [OK]
Hint: Selectors pick data from state, not change it [OK]
Common Mistakes:
  • Confusing selectors with action creators
  • Thinking selectors update state
  • Using selectors to create UI components
2. Which of the following is the correct syntax to define a simple Redux selector function named selectUser that returns state.user?
easy
A. const selectUser = () => state.user;
B. const selectUser = (state) => { state.user }
C. function selectUser() { return user; }
D. const selectUser = state => state.user;

Solution

  1. Step 1: Check function parameter

    A selector receives the whole state as an argument, so it must have state parameter.
  2. Step 2: Check return statement

    The selector returns state.user directly. Arrow function with implicit return is correct.
  3. Final Answer:

    const selectUser = state => state.user; -> Option D
  4. Quick Check:

    Arrow function with state param and return [OK]
Hint: Selector must take state and return part of it [OK]
Common Mistakes:
  • Omitting the state parameter
  • Not returning the value properly
  • Using braces without return statement
3. Given the selector const selectCompletedTodos = state => state.todos.filter(todo => todo.completed); and the state { todos: [{id:1, completed:true}, {id:2, completed:false}, {id:3, completed:true}] }, what will selectCompletedTodos(state) return?
medium
A. [{id:1, completed:true}, {id:3, completed:true}]
B. [{id:2, completed:false}]
C. []
D. undefined

Solution

  1. Step 1: Understand selector logic

    The selector filters todos where completed is true.
  2. Step 2: Apply filter to given state

    Todos with id 1 and 3 have completed:true, so they are included.
  3. Final Answer:

    [{id:1, completed:true}, {id:3, completed:true}] -> Option A
  4. Quick Check:

    Filter completed todos = correct list [OK]
Hint: Filter returns only items matching condition [OK]
Common Mistakes:
  • Selecting incomplete todos instead
  • Returning empty array by mistake
  • Confusing filter with map
4. What is wrong with this selector code?
const selectUserName = state => { state.user.name }
medium
A. It does not return any value explicitly
B. It uses wrong parameter name
C. It should dispatch an action instead
D. It should be a class method

Solution

  1. Step 1: Check function body

    The function uses braces but no return statement, so it returns undefined.
  2. Step 2: Fix by adding return

    Either remove braces or add return to return state.user.name.
  3. Final Answer:

    It does not return any value explicitly -> Option A
  4. Quick Check:

    Missing return in arrow function with braces [OK]
Hint: Arrow with braces needs explicit return [OK]
Common Mistakes:
  • Forgetting return inside braces
  • Confusing selectors with actions
  • Using wrong parameter names
5. You want to create a memoized selector using reselect to get the count of completed todos from state. Which code correctly implements this?
hard
A. import { createSelector } from 'redux'; const selectCompletedCount = createSelector(state => state.todos, todos => todos.length);
B. const selectCompletedCount = state => state.todos.filter(todo => todo.completed).length;
C. import { createSelector } from 'reselect'; const selectTodos = state => state.todos; const selectCompletedCount = createSelector( selectTodos, todos => todos.filter(todo => todo.completed).length );
D. const selectCompletedCount = createSelector(state => state.todos, todos => todos.completed.length);

Solution

  1. Step 1: Use correct import and createSelector

    The createSelector function is imported from 'reselect' and used properly.
  2. Step 2: Define input selector and output function

    selectTodos gets todos array; output function filters completed and counts them.
  3. Step 3: Check other options for errors

    The plain selector const selectCompletedCount = state => state.todos.filter(todo => todo.completed).length is not memoized; importing createSelector from 'redux' is wrong; todos => todos.completed.length accesses property incorrectly.
  4. Final Answer:

    import { createSelector } from 'reselect'; const selectTodos = state => state.todos; const selectCompletedCount = createSelector(selectTodos, todos => todos.filter(todo => todo.completed).length); -> Option C
  5. Quick Check:

    Use reselect createSelector with input and output functions [OK]
Hint: Use createSelector from 'reselect' with input and output functions [OK]
Common Mistakes:
  • Importing createSelector from wrong package
  • Not memoizing selector
  • Incorrectly accessing properties in output function
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard