Why State Management
Local component state (ref, reactive) works well when data belongs to one component. But real apps have state that multiple components need to read and update — and passing that state through props across many layers creates a problem called prop drilling.
The prop drilling problem
Section titled “The prop drilling problem”Imagine FamilyTree without a store. The people array lives in App.vue. Every component that needs it — FocusView, PersonCard, PersonDetailView, all their children — would need to receive it as a prop.
App (owns people[]) └── HomeView (needs people[]) └── FocusView (needs people[]) └── PersonCard (needs people[])Worse: when PersonCard emits select, that event needs to bubble up through every layer before App can update focusPersonId. Then the update needs to propagate back down through props.
This is prop drilling — threading data through components that don’t need it just to reach the ones that do.
What Pinia solves
Section titled “What Pinia solves”Pinia is Vue’s official state management library. Instead of threading data through props, any component can directly read and update shared state:
App ├── FocusView ──────────────────┐ │ └── PersonCard │ ├── PersonDetailView │ All read/write familyStore └── AddPersonView ──────────────┘Each component imports the store and uses it directly. No prop drilling. No event chains. The store is the single source of truth.
When you need a store
Section titled “When you need a store”Not all state belongs in a store. Use local component state for:
- UI-only state that only the current component cares about (is this dropdown open? is this input focused?)
- Form field values before submission
- Transient error messages
Use a store for:
- Data that multiple components need to read (the
peoplearray) - Data that multiple components need to update (adding, editing, deleting people)
- State that needs to persist across navigation (the focus person)
FamilyTree uses a single familyStore that holds the entire people array, all relationship-management actions, and the current focusPersonId.
Exercise
Section titled “Exercise”Think about FamilyTree and answer:
- Name three pieces of state that belong in a store and explain why.
- Name two pieces of state that belong in a local component ref and explain why.
- What would break if
FocusViewowned thepeoplearray instead of a store?
- Prop drilling is the pattern of passing state through intermediate components that don’t use it.
- Pinia provides a global store that any component can access directly — eliminating prop drilling.
- Use local state for UI-only and transient state; use a store for shared, persistent, or multi-component state.