0
0
React Nativemobile~20 mins

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

Choose your learning style9 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.