Some checks are pending
Auto-update PR branches / Update open PR branches (push) Waiting to run
CI / Frontend Static Quality Checks (push) Waiting to run
CI / Frontend Tests & Coverage (push) Waiting to run
CI / Rust Tests & Quality Checks (push) Waiting to run
CI / Linux build verification (push) Waiting to run
Deploy docs / Build VitePress site (push) Waiting to run
Deploy docs / Deploy to GitHub Pages (push) Blocked by required conditions
Release (Alpha) / Compute alpha version (push) Waiting to run
Release (Alpha) / Build release artifacts (push) Blocked by required conditions
Release (Alpha) / GitHub Release (alpha) (push) Blocked by required conditions
Release (Alpha) / Update docs and release pages (push) Blocked by required conditions
Source snapshot: 514ab1975951d94342ea38e64101d5a0f1c51c77
2.0 KiB
2.0 KiB
type, id, title, status, date, superseded_by
| type | id | title | status | date | superseded_by |
|---|---|---|---|---|---|
| ADR | 0026 | Props-down callbacks-up (no global state management) | superseded | 2026-02-15 | 0115 |
Context
React apps commonly adopt global state management libraries (Redux, Zustand, Jotai, Context) to share state across components. For Laputa, the component tree is relatively shallow (App → panels → sub-components), and the data flow is predictable. Adding a state management library would increase complexity without proportional benefit.
Decision
No global state management (no Redux, no Context for data). App.tsx owns the state and passes it down as props. Child-to-parent communication uses callback props (onSelectNote, onCloseTab, etc.). Local state uses useState/useReducer.
Options considered
- Option A (chosen): Props-down, callbacks-up — simple, predictable data flow, easy to trace state changes, no library dependency. Downside: prop drilling through deep trees, verbose parent components.
- Option B: Redux/Zustand global store — centralized state, easy cross-component access. Downside: boilerplate, indirection, harder to trace state changes, over-engineering for a single-window app.
- Option C: React Context for shared state — built-in, no library. Downside: re-renders on any context value change, performance issues with large state objects.
Consequences
App.tsxis the state orchestrator — it holds vault entries, active note, sidebar selection, and all top-level state.- Components receive data and callbacks as props — no
useContextfor data access. - Hooks (
useVaultLoader,useNoteActions,useTabManagement, etc.) encapsulate state logic but return values consumed byApp.tsx. - Prop drilling is mitigated by composing hooks and keeping the component tree shallow.
- Components are easy to test in isolation (just pass props).
- Re-evaluation trigger: if the component tree deepens significantly or cross-cutting state becomes unmanageable with props.