Skip to content
Development
Agent

state-management

<!-- Loaded by react-native-engineer when task involves useState, derived state, Zustand, state structure, dispatchers, ground truth -->

From plugin
vexjoy-agent
449198 skills198 agents12 commands83 hooks

Claude Code

$ npx -y skills add notque/vexjoy-agent --agent claude-code

Agent definition

state-management.md

State Management Reference

<!-- Loaded by react-native-engineer when task involves useState, derived state, Zustand, state structure, dispatchers, ground truth -->

Use Dispatch Updaters When Next State Depends on Current

**Impact:** MEDIUM — prevents stale closures

**Instead of:**

const onLayout = (e: LayoutChangeEvent) => {
  const { width, height } = e.nativeEvent.layout
  if (size?.width !== width || size?.height !== height) setSize({ width, height })
}

**Use:**

const onLayout = (e: LayoutChangeEvent) => {
  const { width, height } = e.nativeEvent.layout
  setSize((prev) => {
    if (prev?.width === width && prev?.height === height) return prev
    return { width, height }
  })
}

For simple cases: `setCount((prev) => prev + 1)` instead of `setCount(count + 1)`.

Not needed for primitive state set to a new value directly.

---

Use Fallback State — undefined Means "User Hasn't Chosen Yet"

**Impact:** MEDIUM — reactive fallbacks, no stale initialState

**Instead of:**

const [enabled, setEnabled] = useState(defaultEnabled)  // locks at mount

**Use:**

const [_enabled, setEnabled] = useState<boolean | undefined>(undefined)
const enabled = _enabled ?? defaultEnabled
// undefined = user hasn't touched it — falls back to parent prop
// Once user interacts, their choice persists

With server data:

const [_theme, setTheme] = useState<string | undefined>(undefined)
const theme = _theme ?? data.theme

---

Minimize State — Derive Values During Render

**Impact:** MEDIUM — fewer re-renders, no state drift

**Instead of:**

const [total, setTotal] = useState(0)
useEffect(() => { setTotal(items.reduce(...)) }, [items])

**Use:**

const total = items.reduce((sum, item) => sum + item.price, 0)
const itemCount = items.length

State is the minimal source of truth. Everything else is derived.

---

State Must Represent Ground Truth

**Impact:** HIGH — single source of truth, easier debugging

State variables represent what is happening (`pressed`, `progress`, `isOpen`), not derived visuals (`scale`, `opacity`, `height`). Derive visuals from state.

**Instead of:**

const [isExpanded, setIsExpanded] = useState(false)
const [height, setHeight] = useState(0)
useEffect(() => { setHeight(isExpanded ? 200 : 0) }, [isExpanded])

**Use:**

const [isExpanded, setIsExpanded] = useState(false)
const height = isExpanded ? 200 : 0

Same principle applies to Reanimated shared values — see `animation-patterns.md`.

---

Track Scroll Position in Shared Values or Refs

**Impact:** HIGH — prevents render thrashing during scroll

Scroll events fire 60/s. `useState` for scroll position = re-render every frame = dropped frames.

**Instead of:**

const [scrollY, setScrollY] = useState(0)
const onScroll = (e) => setScrollY(e.nativeEvent.contentOffset.y)

**Use (Reanimated for scroll-driven animations):**

const scrollY = useSharedValue(0)
const onScroll = useAnimatedScrollHandler({
  onScroll: (e) => { scrollY.value = e.contentOffset.y }
})
return <Animated.ScrollView onScroll={onScroll} scrollEventThrottle={16} />

**Use (ref for non-reactive tracking):**

const scrollY = useRef(0)
const onScroll = (e) => { scrollY.current = e.nativeEvent.contentOffset.y }
Read more
@notque
Ships withvexjoy-agent

Essays and writing behind this toolkit live at vexjoy.com. VexJoy Agent connects plain-English requests to specialist agents, skills, and workflows. /do selects the knowledge and tools needed for your task.

44964 skills198 agents
Get the whole plugin

Stars on GitHub

Momentum

stars in total
449
Star history of notque/vexjoy-agent on GitHub, a chart by star-history.com

Other agents on vexjoy-agent.

modules

modules

Agent

**Scope**: Module selection patterns, builtin vs command/shell decisions, collection modules, and version-specific module changes…

@notque@notqueInstall Agent
testing

testing

Agent

**Scope**: Molecule test scenarios, ansible-lint rules, idempotency validation, and check-mode patterns **Version range**:…

@notque@notqueInstall Agent
communication-patterns

communication-patterns

Agent

**Scope**: Failure modes in agent output style — over-reporting, self-congratulation, verbose narration, and hedging. Covers what…

@notque@notqueInstall Agent

More agents from other plugins.

a11y-architect
Auto-invoked

a11y-architect

Agent

Accessibility Architect specializing in WCAG 2.2 compliance for Web and Native platforms. Use PROACTIVELY when designing UI…

ecc13d293k
@affaan-m@affaan-mInstall Agent
analyze-pass-impact

analyze-pass-impact

Agent

Analyzes how a specific topic affects a group of compiler passes. Used by the /plan-update skill to parallelize research across…

react2d252k
@facebook@facebookInstall Agent
orchestrator

orchestrator

Agent

- If the user makes a simple request (such as asking for the time) which you can fulfill by running a terminal command (such as…

codex2d135k
@openai@openaiInstall Agent
cavecrew-builder

cavecrew-builder

Agent

Surgical 1-2 file edit. Typo fixes, single-function rewrites, mechanical renames, comment removal, format-preserving tweaks. Hard…

caveman3d119k
@juliusbrussee@juliusbrusseeInstall Agent

Questions about state-management.

Which coding agents can use state-management?
state-management installs in Claude Code and Cursor: each loads subagents from .claude/agents, so copy the file there. Flowy's auto-invocation runs in Claude Code only.