CodeBlanks Logo Icon CodeBlanks

Filter and summary

Add active/completed filters and the remaining count.

Filter and summary

The final lesson will assemble TodoApp and add filter and summary. The filter state: "all", "active", "done". Visible todos are computed based on this filter.

Derived state can be computed without useMemo: on each render, const visible = todos.filter(t => ...). React already does this fast; useMemo is used only in extreme cases.

Summary: const remaining = todos.filter(t => !t.done).length. The screen shows <p>{ '{ remaining }' } remaining</p>.

Three pieces merge

TodoApp merges TodoForm and TodoList. The handleAdd function adds a new todo; handleToggle flips the done flag.

visible is computed on each render based on the filter and passed to TodoList as todos={ '{ visible }' }. So the list renders only visible items.

For the summary, remaining is computed separately and printed. This is where the three lessons meet; all pieces work together in one file.

Practice TodoApp full

Complete the skeleton. Write a TodoApp component. Define three states: todos, text, filter. Compute visible with the filter. Compute remaining. Inside <main>, show <h1>Todo</h1>, <p>{ '{ remaining }' } remaining</p>, and <ul> with visible.map. Export it.

Starter code

App.jsx
import { useState } from "react";

// Write the TodoApp component here

Sample solution

App.jsx
import { useState } from "react";

function TodoApp() {
  const [todos, setTodos] = useState([]);
  const [text, setText] = useState("");
  const [filter, setFilter] = useState("all");
  const visible = filter === "all" ? todos : todos.filter((t) => filter === "done" ? t.done : !t.done);
  const remaining = todos.filter((t) => !t.done).length;
  return (
    <main>
      <h1>Todo</h1>
      <p>{remaining} remaining</p>
      <ul>
        {visible.map((todo) => (
          <li key={todo.id}>{todo.text}</li>
        ))}
      </ul>
    </main>
  );
}

export default TodoApp;

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 Derived data

Question
Visible todos are computed with ____.
Answer
Visible todos are computed with filter.

Explanation: filter selects visible todos.

2 Where should derived data be computed?

  • In localStorage
  • In the render body Correct answer
  • In useRef
  • Inside useEffect

Explanation: Computed in the render body.

3 Match the filter options

Term Meaning
all All
active To do
done Completed
remaining Left

All lessons in Beginner