963 markdown files reformatted with the repository's pinned prettier so pnpm format:check covers the folded tree like every other repo file. The formatter's embedded-language pass also normalized code fences (TS semicolons, closed HTML tags in examples, lowercased CSS hex colors, one renumbered list that skipped an index). Alphanumeric token deltas vs the fold commit were audited file-by-file; all are formatter-equivalent markup normalizations plus the four sanitized skills.
2.1 KiB
2.1 KiB
title, impact, impactDescription, tags
| title | impact | impactDescription | tags |
|---|---|---|---|
| State Must Represent Ground Truth | HIGH | cleaner logic, easier debugging, single source of truth | 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):
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):
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.
- Single source of truth — The state (
pressed) describes what's happening; visuals are derived - Easier to extend — Adding opacity, rotation, or other effects just requires more interpolations from the same state
- Debugging — Inspecting
pressed = 1is clearer thanscale = 0.95 - Reusable logic — The same
pressedvalue can drive multiple visual properties
Same principle for React state:
// 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.