AgentStack
SKILL verified MIT Self-run

React Patterns

skill-chandrudp29-skillhub-react-patterns · by chandrudp29

React production patterns — hooks, state management, performance optimization, and component design. Use when building React components, reviewing React code, or fixing React performance issues.

No reviews yet
0 installs
21 views
0.0% view→install

Install

$ agentstack add skill-chandrudp29-skillhub-react-patterns

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of React Patterns? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

React Patterns

Modern React (18+) patterns for production. TypeScript assumed.

When to Use

  • Building new React components or pages
  • Reviewing React code for quality or performance
  • Debugging re-renders or stale state
  • Deciding where to put state

Component Design

Small, focused, composable:

// Bad — one component doing too much
function UserDashboard({ userId }: { userId: string }) {
  const [user, setUser] = useState(null);
  const [orders, setOrders] = useState([]);
  const [notifications, setNotifications] = useState([]);
  // 300 lines of JSX mixing user info, orders table, notification bell...
}

// Good — composed from focused pieces
function UserDashboard({ userId }: { userId: string }) {
  return (
    
      
      
      
    
  );
}

Hooks Patterns

Data Fetching

// Custom hook — logic separate from UI
function useUser(userId: string) {
  const [user, setUser] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    let cancelled = false;   // prevent state update after unmount
    setLoading(true);
    fetchUser(userId)
      .then(data => { if (!cancelled) setUser(data); })
      .catch(err => { if (!cancelled) setError(err); })
      .finally(() => { if (!cancelled) setLoading(false); });
    return () => { cancelled = true; };
  }, [userId]);

  return { user, loading, error };
}

// Use it in the component — clean separation
function UserProfile({ userId }: { userId: string }) {
  const { user, loading, error } = useUser(userId);
  if (loading) return ;
  if (error) return ;
  if (!user) return null;
  return {user.name};
}

Use React Query / TanStack Query instead of manual useEffect for data fetching in real apps:

import { useQuery } from "@tanstack/react-query";

function UserProfile({ userId }: { userId: string }) {
  const { data: user, isLoading, error } = useQuery({
    queryKey: ["user", userId],
    queryFn: () => fetchUser(userId),
    staleTime: 5 * 60 * 1000,  // 5 minutes
  });
  // handles caching, deduplication, background refresh automatically
}

State Management

Where to put state:

| State type | Where | |---|---| | UI state (open/closed, selected tab) | useState in the component | | Shared UI state (theme, sidebar) | React Context | | Server state (user data, API responses) | React Query / SWR | | Complex client state | Zustand / Jotai |

// Context for shared UI state — not for server data
const ThemeContext = createContext void } | null>(null);

export function ThemeProvider({ children }: { children: ReactNode }) {
  const [theme, setTheme] = useState("light");
  const toggle = useCallback(() => setTheme(t => t === "light" ? "dark" : "light"), []);
  return {children};
}

export function useTheme() {
  const ctx = useContext(ThemeContext);
  if (!ctx) throw new Error("useTheme must be inside ThemeProvider");
  return ctx;
}

Performance

useCallback and useMemo — only when there's a measurable problem:

// Use useMemo for expensive computations
const sortedItems = useMemo(
  () => items.sort((a, b) => b.score - a.score),
  [items]  // recalculate only when items changes
);

// Use useCallback for functions passed to memoized children
const handleSelect = useCallback((id: string) => {
  setSelectedIds(prev => [...prev, id]);
}, []);  // stable reference — won't trigger child re-renders

Don't add useMemo/useCallback everywhere "just in case". Profile first with React DevTools.

Avoid re-renders:

// BAD — new object created on every render

// GOOD — stable reference
const style = { color: "red" } as const;

// Or with useMemo if it depends on props/state
const style = useMemo(() => ({ color: isError ? "red" : "green" }), [isError]);

List rendering:

// Always key by stable, unique ID — never array index for dynamic lists
{items.map(item => (
    // id, not index
))}

TypeScript Patterns

// Props: explicit interface, not inline type
interface ButtonProps {
  label: string;
  onClick: () => void;
  variant?: "primary" | "secondary" | "danger";
  disabled?: boolean;
}

// Component return type
function Button({ label, onClick, variant = "primary", disabled = false }: ButtonProps): JSX.Element {
  return (
    
      {label}
    
  );
}

// Event handlers
const handleChange = (e: React.ChangeEvent) => {
  setValue(e.target.value);
};

// Ref typing
const inputRef = useRef(null);

Common Mistakes

| Mistake | Fix | |---|---| | useEffect with missing deps | Add missing deps or use useCallback to stabilize functions | | State update after unmount | Add cleanup in useEffect with cancelled flag or AbortController | | Index as list key | Use stable unique IDs | | Fetching in useEffect directly | Use React Query or similar | | Context for server data | Use React Query — Context causes full subtree re-renders |

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.