react-agent
SKILL.md
React Agent
Pragmatic React development that prioritizes simplicity, maintainable state management, and optimal rendering performance.
Core Principles
1. Start Simple, Add Complexity Only When Needed
Default approach:
- Use local state (
useState) first - Lift state up when components need to share
- Add Context only when prop drilling becomes painful (>3 levels)
- Consider external state management (Zustand/Redux) only for truly global state
Red flags of over-engineering:
- Creating abstractions before they're needed
- Adding state management libraries for 2-3 shared values
- Implementing complex patterns for simple forms
- Premature optimization without measuring
2. State Management Decision Tree
Follow this decision tree when choosing state solutions:
Is this state used in only one component?
├─ YES → useState
└─ NO → Is it shared by 2-3 closely related components?
├─ YES → Lift state to nearest common parent
└─ NO → Does it need to be accessed across distant components?
├─ YES → Is it truly global (auth, theme, i18n)?
│ ├─ YES → Context API or Zustand
│ └─ NO → Still use props/composition when possible
└─ NO → Re-evaluate component structure
Quick reference:
- 1 component →
useState - 2-3 related → Lift state + props
- Many components (same branch) → Context API
- App-wide global → Zustand (recommended) or Redux Toolkit
- Server data → TanStack Query or SWR
3. Rendering Optimization Rules
Only optimize when:
- Profiler shows actual performance issue
- Component re-renders are visibly slow
- Working with large lists (>100 items)
- Expensive computations are occurring
Optimization toolkit:
React.memo- for expensive components that receive same propsuseMemo- for expensive calculationsuseCallback- when passing callbacks to memoized childrenuseTransition- for non-urgent updates (React 18+)
Don't optimize prematurely:
- Avoid wrapping everything in
memoby default - Don't use
useMemofor simple calculations - Don't optimize before measuring
Quick Start Workflow
1. Analyze Requirements
// Ask yourself:
// - What data do I need? (local vs shared)
// - How many components need this data?
// - Is this data from server or client?
// - Are there performance concerns?
2. Choose State Pattern
See references/state-patterns.md for detailed patterns and examples.
Local State Example:
function Counter() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(c => c + 1)}>{count}</button>;
}
Lifted State Example:
function Parent() {
const [items, setItems] = useState([]);
return (
<>
<ItemList items={items} />
<ItemForm onAdd={(item) => setItems([...items, item])} />
</>
);
}
3. Implement with TypeScript
// Always type props and state
interface Props {
userId: string;
onUpdate: (data: UserData) => void;
}
function UserProfile({ userId, onUpdate }: Props) {
const [isLoading, setIsLoading] = useState(false);
// implementation
}
4. Add Optimization (Only If Needed)
// Measure first with React DevTools Profiler
// Then optimize specific bottlenecks
const MemoizedList = memo(ExpensiveList);
const handleClick = useCallback(() => {
// Only when passing to memoized children
}, [dependencies]);
const expensiveValue = useMemo(() => {
// Only for truly expensive calculations
return heavyComputation(data);
}, [data]);
Common Patterns
Pattern 1: Form Handling
Simple form (controlled):
function SimpleForm() {
const [email, setEmail] = useState('');
const handleSubmit = (e: FormEvent) => {
e.preventDefault();
// handle submission
};
return (
<form onSubmit={handleSubmit}>
<input
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
</form>
);
}
Complex form: Use React Hook Form or Formik (only for 5+ fields)
Pattern 2: Data Fetching
// Prefer TanStack Query for server state
import { useQuery } from '@tanstack/react-query';
function UserProfile({ userId }: Props) {
const { data, isLoading, error } = useQuery({
queryKey: ['user', userId],
queryFn: () => fetchUser(userId),
});
if (isLoading) return <Spinner />;
if (error) return <Error error={error} />;
return <div>{data.name}</div>;
}
Pattern 3: Conditional Rendering
// Simple ternary
{isLoading ? <Spinner /> : <Content />}
// Multiple conditions - extract to variable
const content = (() => {
if (isLoading) return <Spinner />;
if (error) return <Error />;
if (!data) return <Empty />;
return <Content data={data} />;
})();
Performance Checklist
Before optimizing, verify with React DevTools Profiler:
- Identify which components re-render
- Measure render time
- Check why re-renders happen (props/state/context)
Quick wins:
- Extract expensive operations outside component
- Use proper key props for lists (not index unless static)
- Split large components into smaller ones
- Use Code Splitting for large bundles (
React.lazy)
For lists:
// Virtualization for 100+ items
import { useVirtualizer } from '@tanstack/react-virtual';
// Key requirement: stable, unique IDs
{items.map(item => (
<Item key={item.id} {...item} />
))}
Anti-Patterns to Avoid
❌ Over-abstraction:
// Don't create generic wrappers unnecessarily
<GenericForm config={complexConfig} />
❌ Premature memoization:
// Don't wrap everything by default
export default memo(SimpleButton); // unnecessary
❌ Prop drilling Context:
// Don't use Context just to avoid 2 levels of props
<Context.Provider value={simpleValue}>
❌ Mutations:
// Never mutate state
items.push(newItem); // Wrong
setItems([...items, newItem]); // Correct
References
Load these references for deeper guidance:
- State Management →
references/state-patterns.md- Detailed patterns with examples - Performance →
references/performance-guide.md- Optimization techniques and profiling - TypeScript →
references/typescript-patterns.md- Type patterns and utilities - Hooks →
references/hooks-guide.md- Custom hooks and patterns - Testing →
references/testing-guide.md- Testing with React Testing Library
Key Constraints
MUST DO:
- Type all props and state with TypeScript
- Use stable keys for lists (not array index for dynamic lists)
- Clean up effects (return cleanup function)
- Handle loading and error states
- Validate before optimizing (use Profiler)
MUST NOT:
- Mutate state or props
- Use index as key for dynamic lists
- Create functions inside JSX
- Forget useEffect cleanup (memory leaks)
- Over-engineer simple solutions
- Optimize without measuring
Weekly Installs
3
Repository
eva813/vue3-skillsGitHub Stars
1
First Seen
Feb 26, 2026
Security Audits
Installed on
opencode3
gemini-cli3
github-copilot3
codex3
kimi-cli3
amp3