skills/react/SKILL.md
Use when editing React code, .tsx or .jsx files, react imports, components, hooks, state, client components, framework-scoped server components, backend API integration, or React upgrades.
npx skillsauth add cofin/flow reactInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
import { useState, useEffect, useCallback } from 'react';
interface Props {
title: string;
items: Item[];
onSelect?: (item: Item) => void;
}
export function ItemList({ title, items, onSelect }: Props) {
const [selected, setSelected] = useState<Item | null>(null);
const handleSelect = useCallback((item: Item) => {
setSelected(item);
onSelect?.(item);
}, [onSelect]);
return (
<div>
<h2>{title}</h2>
<ul>
{items.map(item => (
<li key={item.id} onClick={() => handleSelect(item)}>
{item.name}
</li>
))}
</ul>
</div>
);
}
</example>
function useFetch<T>(url: string) {
const [data, setData] = useState<T | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<Error | null>(null);
useEffect(() => {
const controller = new AbortController();
fetch(url, { signal: controller.signal })
.then(res => {
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json();
})
.then(setData)
.catch(err => {
if (err.name !== 'AbortError') setError(err);
})
.finally(() => setLoading(false));
return () => controller.abort();
}, [url]);
return { data, loading, error };
}
</example>
// Server Components are framework-scoped (for example Next.js App Router)
// and are not a universal default in plain React + Vite projects.
async function UserProfile({ userId }: { userId: string }) {
const user = await fetchUser(userId);
return <div>{user.name}</div>;
}
// Client Component
'use client';
export function InteractiveButton({ onClick }: { onClick: () => void }) {
return <button onClick={onClick}>Click me</button>;
}
</example>
import { useActionState } from 'react';
function ContactForm() {
const [state, formAction, isPending] = useActionState(
async (prevState: FormState, formData: FormData) => {
const result = await submitForm(formData);
return result;
},
{ message: '' }
);
return (
<form action={formAction}>
<input name="email" type="email" required />
<button type="submit" disabled={isPending}>
{isPending ? 'Sending...' : 'Send'}
</button>
{state.message && <p>{state.message}</p>}
</form>
);
}
</example>
import { createContext, useContext, useState, ReactNode } from 'react';
interface ThemeContextType {
theme: 'light' | 'dark';
toggle: () => void;
}
const ThemeContext = createContext<ThemeContextType | null>(null);
export function ThemeProvider({ children }: { children: ReactNode }) {
const [theme, setTheme] = useState<'light' | 'dark'>('light');
const toggle = () => setTheme(t => t === 'light' ? 'dark' : 'light');
return (
<ThemeContext.Provider value={{ theme, toggle }}>
{children}
</ThemeContext.Provider>
);
}
export function useTheme() {
const context = useContext(ThemeContext);
if (!context) throw new Error('useTheme must be used within ThemeProvider');
return context;
}
</example>
</workflow>
<guardrails>
useCallback/useMemo only when profiling shows measurable benefitkey props correctly (stable, unique identifiers)useEffect return functionFor comprehensive coverage of these commonly-used React libraries:
| Library | Skill | Coverage |
|---------|-------|----------|
| TanStack Router/Query/Table/Form | tanstack | Full ecosystem |
| Shadcn/ui components | shadcn | All components |
| Tailwind CSS | tailwind | Styling patterns |
Bundle traditional SPA apps into static sets:
vite build
Align Server Actions and components to runtimes offering full Server-Side script continuity safely supporting 'use server' handlers.
Example GitHub Actions workflow for static build:
name: React CI
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'npm'
- run: npm ci
- run: npm run build
</example>
Add validation instructions here. </validation>
development
Use when tracing execution paths, mapping dependencies, understanding unfamiliar code, following data flow, investigating end-to-end behavior, debugging call chains, or deciding which files to read next.
development
Use when reviewing authentication, authorization, user input, secrets, API keys, database queries, file uploads, session management, external API calls, OWASP risks, or data handling attack surface.
testing
Use when analyzing tradeoffs, comparing approaches, weighing options, assessing risks, stress-testing conclusions, identifying blind spots, or applying multiple viewpoints to a decision.
development
Use when reviewing hot paths, slow code, database queries, N+1 risks, memory usage, loops, I/O, caching strategy, concurrency, latency-sensitive paths, or resource efficiency.