Project: Todo With Zustand

Introduction

This project builds a Todo app with Zustand, filtered views (all / active / completed), and optional localStorage persistence. No backend—focus on state design, component structure, and immutable updates before API projects.

Prerequisites

Sister project: Vue Todo with Pinia.

Goals

FeatureSkill
Add / toggle / remove todosZustand actions
Filters all / active / doneSelectors in store
Persist todospersist middleware or manual save
Component splitInput, item, filter bar

Store Design

src/stores/todoStore.ts:

Components

TodoInput.tsx:

TodoItem.tsx:

TodoApp.tsx:

Deliverables

  • Add, toggle, delete todos
  • Three filters work
  • activeCount updates
  • Todos survive refresh (persist)
  • Empty state when no todos

Extensions

  • Edit todo inline (double-click)
  • Sync ?filter=active with React Router search params
  • Replace persist with FastAPI CRUD

FAQ

Selector calls function every render?

filteredItems as getter—call s.filteredItems() in selector or compute in component with useMemo from items + filter.

persist vs manual localStorage?

persist middleware is cleaner—shown above.

Test store?

Reset with useTodoStore.setState({ items: [], filter: "all" })Testing.

Next project?

Blog Reader With API.