Pulled ALL skills from 15 source repositories: - anthropics/skills: 16 (docs, design, MCP, testing) - obra/superpowers: 14 (TDD, debugging, agents, planning) - coreyhaines31/marketingskills: 25 (marketing, CRO, SEO, growth) - better-auth/skills: 5 (auth patterns) - vercel-labs/agent-skills: 5 (React, design, Vercel) - antfu/skills: 16 (Vue, Vite, Vitest, pnpm, Turborepo) - Plus 13 individual skills from various repos Mosaic Stack is not limited to coding — the Orchestrator and subagents serve coding, business, design, marketing, writing, logistics, analysis, and more. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
81 lines
2.1 KiB
Markdown
81 lines
2.1 KiB
Markdown
---
|
|
title: State Must Represent Ground Truth
|
|
impact: HIGH
|
|
impactDescription: cleaner logic, easier debugging, single source of truth
|
|
tags: state, derived-state, reanimated, hooks
|
|
---
|
|
|
|
## State Must Represent Ground Truth
|
|
|
|
State variables—both React `useState` and Reanimated shared values—should
|
|
represent the actual state of something (e.g., `pressed`, `progress`, `isOpen`),
|
|
not derived visual values (e.g., `scale`, `opacity`, `translateY`). Derive
|
|
visual values from state using computation or interpolation.
|
|
|
|
**Incorrect (storing the visual output):**
|
|
|
|
```tsx
|
|
const scale = useSharedValue(1)
|
|
|
|
const tap = Gesture.Tap()
|
|
.onBegin(() => {
|
|
scale.set(withTiming(0.95))
|
|
})
|
|
.onFinalize(() => {
|
|
scale.set(withTiming(1))
|
|
})
|
|
|
|
const animatedStyle = useAnimatedStyle(() => ({
|
|
transform: [{ scale: scale.get() }],
|
|
}))
|
|
```
|
|
|
|
**Correct (storing the state, deriving the visual):**
|
|
|
|
```tsx
|
|
const pressed = useSharedValue(0) // 0 = not pressed, 1 = pressed
|
|
|
|
const tap = Gesture.Tap()
|
|
.onBegin(() => {
|
|
pressed.set(withTiming(1))
|
|
})
|
|
.onFinalize(() => {
|
|
pressed.set(withTiming(0))
|
|
})
|
|
|
|
const animatedStyle = useAnimatedStyle(() => ({
|
|
transform: [{ scale: interpolate(pressed.get(), [0, 1], [1, 0.95]) }],
|
|
}))
|
|
```
|
|
|
|
**Why this matters:**
|
|
|
|
State variables should represent real "state", not necessarily a desired end
|
|
result.
|
|
|
|
1. **Single source of truth** — The state (`pressed`) describes what's
|
|
happening; visuals are derived
|
|
2. **Easier to extend** — Adding opacity, rotation, or other effects just
|
|
requires more interpolations from the same state
|
|
3. **Debugging** — Inspecting `pressed = 1` is clearer than `scale = 0.95`
|
|
4. **Reusable logic** — The same `pressed` value can drive multiple visual
|
|
properties
|
|
|
|
**Same principle for React state:**
|
|
|
|
```tsx
|
|
// Incorrect: storing derived values
|
|
const [isExpanded, setIsExpanded] = useState(false)
|
|
const [height, setHeight] = useState(0)
|
|
|
|
useEffect(() => {
|
|
setHeight(isExpanded ? 200 : 0)
|
|
}, [isExpanded])
|
|
|
|
// Correct: derive from state
|
|
const [isExpanded, setIsExpanded] = useState(false)
|
|
const height = isExpanded ? 200 : 0
|
|
```
|
|
|
|
State is the minimal truth. Everything else is derived.
|