react

SKILL.md

Critical Patterns

Custom Hooks (REQUIRED)

// ✅ ALWAYS: Extract reusable logic into custom hooks
function useUser(userId: string) {
  const [user, setUser] = useState<User | null>(null);
  const [loading, setLoading] = useState(true);
  
  useEffect(() => {
    fetchUser(userId).then(setUser).finally(() => setLoading(false));
  }, [userId]);
  
  return { user, loading };
}

// ❌ NEVER: Duplicate logic across components

Component Composition (REQUIRED)

// ✅ ALWAYS: Prefer composition over prop drilling
function Dashboard({ children }: { children: React.ReactNode }) {
  return <div className="dashboard">{children}</div>;
}

// Usage
<Dashboard>
  <Sidebar />
  <MainContent />
</Dashboard>

Memoization (WHEN NEEDED)

// ✅ Use useMemo for expensive calculations
const sortedItems = useMemo(() => 
  items.sort((a, b) => a.name.localeCompare(b.name)),
  [items]
);

// ✅ Use useCallback for stable function references
const handleClick = useCallback((id: string) => {
  setSelected(id);
}, []);

Decision Tree

Need shared state?         → Use Context or Zustand
Need server state?         → Use React Query / SWR
Need form handling?        → Use React Hook Form
Need expensive calc?       → Use useMemo
Need stable callback?      → Use useCallback
Need DOM access?           → Use useRef

Code Examples

Controlled Form

function LoginForm() {
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  
  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    login({ email, password });
  };
  
  return (
    <form onSubmit={handleSubmit}>
      <input 
        type="email" 
        value={email} 
        onChange={(e) => setEmail(e.target.value)} 
      />
      <input 
        type="password" 
        value={password} 
        onChange={(e) => setPassword(e.target.value)} 
      />
      <button type="submit">Login</button>
    </form>
  );
}

Error Boundary

class ErrorBoundary extends React.Component<Props, State> {
  state = { hasError: false };
  
  static getDerivedStateFromError() {
    return { hasError: true };
  }
  
  render() {
    if (this.state.hasError) {
      return <FallbackUI />;
    }
    return this.props.children;
  }
}

Commands

npx create-react-app myapp --template typescript
npm run dev
npm run build
npm run test
Weekly Installs
5
First Seen
Jan 26, 2026
Installed on
github-copilot4
cline3
gemini-cli3
codex3
continue3
cursor3