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
| Feature | Skill |
|---|---|
| Add / toggle / remove todos | Zustand actions |
| Filters all / active / done | Selectors in store |
| Persist todos | persist middleware or manual save |
| Component split | Input, item, filter bar |
Store Design
src/stores/todoStore.ts:
typescript
Components
TodoInput.tsx:
tsx
TodoItem.tsx:
tsx
TodoApp.tsx:
tsx
Deliverables
- Add, toggle, delete todos
- Three filters work
-
activeCountupdates - Todos survive refresh (persist)
- Empty state when no todos
Extensions
- Edit todo inline (double-click)
- Sync
?filter=activewith 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.