All skills
jeffallan avatar

/react-expert

@efebc44
by jeffallanjeffallan/claude-skills12k stars
1,124

Use when building React 18+ applications in .jsx or .tsx files, Next.js App Router projects, or create-react-app setups. Creates components, implements custom hooks, debugs rendering issues, migrates class components to functional, and implements state management. Invoke for Server Components, Suspense boundaries, useActionState forms, performance optimization, or React 19 features.

Use this Skill: https://skilld.dev/gh/jeffallan/claude-skills/react-expert

This session only. Nothing lands on disk.

referenceshooks-patterns.md

≈931 tokens on demand. Your agent reads this file only when SKILL.md points to it.

Hooks Patterns

Custom Hook Pattern

// useApi - Data fetching hook
function useApi<T>(url: string) {
  const [data, setData] = useState<T | null>(null);
  const [error, setError] = useState<Error | null>(null);
  const [loading, setLoading] = useState(true);

  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, error, loading };
}

useDebounce

function useDebounce<T>(value: T, delay: number): T {
  const [debounced, setDebounced] = useState(value);

  useEffect(() => {
    const timer = setTimeout(() => setDebounced(value), delay);
    return () => clearTimeout(timer);
  }, [value, delay]);

  return debounced;
}

// Usage
function Search() {
  const [query, setQuery] = useState('');
  const debouncedQuery = useDebounce(query, 300);

  useEffect(() => {
    if (debouncedQuery) search(debouncedQuery);
  }, [debouncedQuery]);
}

useLocalStorage

function useLocalStorage<T>(key: string, initialValue: T) {
  const [value, setValue] = useState<T>(() => {
    if (typeof window === 'undefined') return initialValue;
    const stored = localStorage.getItem(key);
    return stored ? JSON.parse(stored) : initialValue;
  });

  useEffect(() => {
    localStorage.setItem(key, JSON.stringify(value));
  }, [key, value]);

  return [value, setValue] as const;
}

useMediaQuery

function useMediaQuery(query: string): boolean {
  const [matches, setMatches] = useState(() =>
    typeof window !== 'undefined' && window.matchMedia(query).matches
  );

  useEffect(() => {
    const media = window.matchMedia(query);
    const listener = (e: MediaQueryListEvent) => setMatches(e.matches);

    media.addEventListener('change', listener);
    return () => media.removeEventListener('change', listener);
  }, [query]);

  return matches;
}

// Usage
function Layout() {
  const isMobile = useMediaQuery('(max-width: 768px)');
  return isMobile ? <MobileNav /> : <DesktopNav />;
}

useCallback & useMemo

// useCallback: Memoize functions (for child dependencies)
const handleClick = useCallback((id: string) => {
  setSelected(id);
}, []); // Empty deps = stable reference

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

// When to use:
// - useCallback: When passing to memoized children
// - useMemo: When calculation is expensive AND deps rarely change

Effect Cleanup

useEffect(() => {
  const subscription = api.subscribe(handler);

  // Cleanup function
  return () => subscription.unsubscribe();
}, []);

// Async effect pattern
useEffect(() => {
  let cancelled = false;

  async function fetchData() {
    const data = await api.getData();
    if (!cancelled) setData(data);
  }

  fetchData();
  return () => { cancelled = true };
}, []);

Quick Reference

Hook Purpose
useState Component state
useEffect Side effects, subscriptions
useCallback Memoize functions
useMemo Memoize values
useRef Mutable ref, DOM access
useContext Read context
useReducer Complex state logic
Custom Hook Use Case
useDebounce Input delay
useLocalStorage Persistent state
useMediaQuery Responsive logic
useApi Data fetching

Source: SKILL.md on GitHub

1 alert16d5 checks · Risk CRITICAL
  • Gen Agent Trust Hub16d

    This skill references a blacklisted URL and its primary instruction file has been flagged by automated security scanners for malicious reputation. It also contains instructions for the agent to execute shell commands for type validation, which poses a risk if the instructions themselves are compromised.

  • Socket16d

    No alerts

  • Snyk16d

    Risk: LOW · No issues

  • Runlayer6mo

    8 files scanned · No issues

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at efebc44. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 months ago.

Steadyupdated 5 months ago
Other metadata
metadata
{
  "author": "https://github.com/Jeffallan",
  "version": "1.1.0",
  "domain": "frontend",
  "triggers": "React, JSX, hooks, useState, useEffect, useContext, Server Components, React 19, Suspense, TanStack Query, Redux, Zustand, component, frontend",
  "role": "specialist",
  "scope": "implementation",
  "output-format": "code",
  "related-skills": "fullstack-guardian, playwright-expert, test-master"
}

README badge

README badge for jeffallan/claude-skills/react-expert