rendering-patterns
<!-- Loaded by react-native-engineer when task involves conditional rendering, &&, Text components, React Compiler, memoization -->
$ npx -y skills add notque/vexjoy-agent --agent claude-codeHow it fires
How this agent gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
Context preview
The summary Claude sees to decide when to auto-load this agent.
<!-- Loaded by react-native-engineer when task involves conditional rendering, &&, Text components, React Compiler, memoization -->
Agent definition
rendering-patterns.mdRendering Patterns Reference
<!-- Loaded by react-native-engineer when task involves conditional rendering, &&, Text components, React Compiler, memoization -->
Use Ternary or Explicit Boolean for Conditional Rendering
**Impact:** CRITICAL — prevents hard crash in production
`{value && <Component />}` crashes React Native when `value` is `0` or empty string. These are falsy but JSX-renderable — RN tries to render them as text outside `<Text>`, causing a hard crash. React Native-specific (not a web issue).
**Instead of:**
{name && <Text>{name}</Text>} // crashes if name is ""
{count && <Text>{count} items</Text>} // crashes if count is 0**Use:**
{name ? <Text>{name}</Text> : null}
{count > 0 ? <Text>{count} items</Text> : null}
// Or: {!!name && <Text>{name}</Text>}
// Or: early return — if (!name) return nullEnable `react/jsx-no-leaked-render` ESLint rule.
---
Wrap All Strings in Text Components
**Impact:** CRITICAL — prevents runtime crash
Strings must be inside `<Text>`. React Native throws a hard error on string children of `<View>`.
**Instead of:**
return <View>Hello, {name}!</View>**Use:**
return <View><Text>Hello, {name}!</Text></View>Applies to string literals, template literals, and expressions that evaluate to strings.
---
Destructure Functions Early in Render (React Compiler)
**Impact:** HIGH — stable references, fewer re-renders
With React Compiler, destructure functions from hooks and props at render scope top. The compiler keys cache on read variables — dotting into objects uses the object reference (changes each render).
**Instead of:**
function SaveButton(props) {
const router = useRouter()
const handlePress = () => { props.onSave(); router.push('/success') }
return <Button onPress={handlePress}>Save</Button>
}**Use:**
function SaveButton({ onSave }) {
const { push } = useRouter()
const handlePress = () => { onSave(); push('/success') }
return <Button onPress={handlePress}>Save</Button>
}Only applies with React Compiler enabled. Without it, use standard `useCallback`.
---
Memoization Patterns Without React Compiler
const UserRow = memo(function UserRow({ name, isActive }: Props) {
return <View>{/* ... */}</View>
})
const handlePress = useCallback((id: string) => {
dispatch({ type: 'SELECT', id })
}, [dispatch])
const sorted = useMemo(
() => items.toSorted((a, b) => a.name.localeCompare(b.name)),
[items]
)With React Compiler, `memo()` and `useCallback()` are handled automatically. Object reference stability still matters for virtualized lists.
---
Hoist Intl Formatters to Module Scope
**Impact:** LOW-MEDIUM — avoids expensive instantiation per render
**Instead of:**
function Price({ amount }: { amount: number }) {
const formatter = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' })
return <Text>{formatter.format(amount)}</Text>
}**Use:**
const currencyFormatter = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' })
function Price({ amount }: { amount: number }) {
return <Text>{currencyFormatter.format(amount)}</Text>
}For dynamic locales, memoize: `useMemo(() => new Intl.DateTimeFormat(locale, opts), [locale])`.
Read more
Rendering Patterns Reference
<!-- Loaded by react-native-engineer when task involves conditional rendering, &&, Text components, React Compiler, memoization -->
Use Ternary or Explicit Boolean for Conditional Rendering
**Impact:** CRITICAL — prevents hard crash in production
`{value && <Component />}` crashes React Native when `value` is `0` or empty string. These are falsy but JSX-renderable — RN tries to render them as text outside `<Text>`, causing a hard crash. React Native-specific (not a web issue).
**Instead of:**
{name && <Text>{name}</Text>} // crashes if name is ""
{count && <Text>{count} items</Text>} // crashes if count is 0**Use:**
{name ? <Text>{name}</Text> : null}
{count > 0 ? <Text>{count} items</Text> : null}
// Or: {!!name && <Text>{name}</Text>}
// Or: early return — if (!name) return nullEnable `react/jsx-no-leaked-render` ESLint rule.
---
Wrap All Strings in Text Components
**Impact:** CRITICAL — prevents runtime crash
Strings must be inside `<Text>`. React Native throws a hard error on string children of `<View>`.
**Instead of:**
return <View>Hello, {name}!</View>**Use:**
return <View><Text>Hello, {name}!</Text></View>Applies to string literals, template literals, and expressions that evaluate to strings.
---
Destructure Functions Early in Render (React Compiler)
**Impact:** HIGH — stable references, fewer re-renders
With React Compiler, destructure functions from hooks and props at render scope top. The compiler keys cache on read variables — dotting into objects uses the object reference (changes each render).
**Instead of:**
function SaveButton(props) {
const router = useRouter()
const handlePress = () => { props.onSave(); router.push('/success') }
return <Button onPress={handlePress}>Save</Button>
}**Use:**
function SaveButton({ onSave }) {
const { push } = useRouter()
const handlePress = () => { onSave(); push('/success') }
return <Button onPress={handlePress}>Save</Button>
}Only applies with React Compiler enabled. Without it, use standard `useCallback`.
---
Memoization Patterns Without React Compiler
const UserRow = memo(function UserRow({ name, isActive }: Props) {
return <View>{/* ... */}</View>
})
const handlePress = useCallback((id: string) => {
dispatch({ type: 'SELECT', id })
}, [dispatch])
const sorted = useMemo(
() => items.toSorted((a, b) => a.name.localeCompare(b.name)),
[items]
)With React Compiler, `memo()` and `useCallback()` are handled automatically. Object reference stability still matters for virtualized lists.
---
Hoist Intl Formatters to Module Scope
**Impact:** LOW-MEDIUM — avoids expensive instantiation per render
**Instead of:**
function Price({ amount }: { amount: number }) {
const formatter = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' })
return <Text>{formatter.format(amount)}</Text>
}**Use:**
const currencyFormatter = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' })
function Price({ amount }: { amount: number }) {
return <Text>{currencyFormatter.format(amount)}</Text>
}For dynamic locales, memoize: `useMemo(() => new Intl.DateTimeFormat(locale, opts), [locale])`.
Essays and writing behind this toolkit live at vexjoy.com. AI agents skip steps. "Looks correct" replaces running tests. "Trivial change" replaces verification.
Repo: notque/vexjoy-agent
Other agents on vexjoy-agent.
- ansible-automation-engineer
Ansible automation: playbooks, roles, collections, Molecule testing, Vault security.
Open agent - modules
**Scope**: Module selection patterns, builtin vs command/shell decisions, collection modules, and version-specific module changes **Version range**: ansible-core 2.14+ / Ansible Collections (community.general 7.0+) **Generated**: 2026-04-04 — verify against current Ansible
Open agent - testing
**Scope**: Molecule test scenarios, ansible-lint rules, idempotency validation, and check-mode patterns **Version range**: Molecule 6.0+ / ansible-lint 6.0+ / ansible-core 2.14+ **Generated**: 2026-04-04 — verify against current Molecule and ansible-lint documentation
Open agent - base-instructions
Universal operational rules injected by /do at agent dispatch. Domain-specific rules live in each agent's .md file.
Open agent - communication-patterns
**Scope**: Failure modes in agent output style — over-reporting, self-congratulation, verbose narration, and hedging. Covers what to detect and how to fix each. **Version range**: all versions **Generated**: 2026-05-11
Open agent - combat-effects-upgrade
Zero-dependency combat visual upgrades: CSS particle replacement, Framer Motion combat juice, CSS 3D card transforms.
Open agent

