Skip to content

Instantly share code, notes, and snippets.

@frankdilo
Created January 28, 2026 14:45
Show Gist options
  • Select an option

  • Save frankdilo/dcd0baa30e16f7653a559c8946017781 to your computer and use it in GitHub Desktop.

Select an option

Save frankdilo/dcd0baa30e16f7653a559c8946017781 to your computer and use it in GitHub Desktop.
Claude Code skill: Review React code for unnecessary useEffect usage

Review React code for unnecessary useEffect usage based on react.dev guidelines.

Arguments:

  • $ARGUMENTS: Optional scope to analyze (default: current git changes). Examples: "diff to main", "src/components/", "whole codebase"

Guidelines from react.dev

Before reviewing, internalize these principles:

You DON'T need useEffect for:

  1. Transforming data for rendering - Calculate during render instead

    // Bad
    const [fullName, setFullName] = useState('');
    useEffect(() => {
      setFullName(firstName + ' ' + lastName);
    }, [firstName, lastName]);
    
    // Good
    const fullName = firstName + ' ' + lastName;
  2. Caching expensive calculations - Use useMemo instead

    // Bad
    useEffect(() => {
      setFilteredList(items.filter(predicate));
    }, [items]);
    
    // Good
    const filteredList = useMemo(() => items.filter(predicate), [items]);
  3. Resetting state when a prop changes - Use a key instead

    // Bad
    useEffect(() => {
      setComment('');
    }, [userId]);
    
    // Good
    <Profile userId={userId} key={userId} />
  4. Adjusting state when a prop changes - Calculate during render

    // Bad
    useEffect(() => {
      setSelection(null);
    }, [items]);
    
    // Good
    const [prevItems, setPrevItems] = useState(items);
    if (items !== prevItems) {
      setPrevItems(items);
      setSelection(null);
    }
  5. Sharing logic between event handlers - Extract to a function

    // Bad
    useEffect(() => {
      if (product.isInCart) {
        showNotification(`Added ${product.name} to cart!`);
      }
    }, [product]);
    
    // Good
    function buyProduct() {
      addToCart(product);
      showNotification(`Added ${product.name} to cart!`);
    }
  6. Sending POST requests on form submit - Handle in the event handler

    // Bad
    useEffect(() => {
      if (submitted) {
        post('/api/submit', { data });
      }
    }, [submitted]);
    
    // Good
    function handleSubmit() {
      post('/api/submit', { data });
    }
  7. Chains of computations - Calculate in render or event handlers

  8. Initializing the application - Do it outside the component or use a flag

    // Bad
    useEffect(() => {
      loadDataFromLocalStorage();
    }, []);
    
    // Good (outside component)
    if (typeof window !== 'undefined') {
      loadDataFromLocalStorage();
    }
  9. Notifying parent components about state changes - Pass callbacks instead

  10. Passing data to parent - Lift state up instead

You DO need useEffect for:

  • Synchronizing with external systems (DOM, network, third-party widgets)
  • Setting up subscriptions
  • Fetching data (though consider React Query, SWR, or RSC instead)
  • Measuring DOM elements after render

Workflow

  1. Determine scope: Use $ARGUMENTS if provided, otherwise analyze uncommitted changes via git diff

  2. Find useEffect usage: Search for useEffect calls in the target scope

  3. Analyze each useEffect:

    • What is it doing?
    • Does it match any of the anti-patterns above?
    • Is it truly synchronizing with an external system?
  4. Report findings: For each unnecessary useEffect, explain:

    • The file and line number
    • Why it's unnecessary
    • The recommended fix with code example
  5. Apply fixes: After showing proposed changes, ask if the user wants them applied

Important notes

  • Be conservative: if unsure whether an effect is necessary, explain the tradeoff rather than removing it
  • Consider the broader context (data fetching libraries, framework patterns)
  • Some effects that look unnecessary may be intentional for specific reasons
  • Prioritize readability and maintainability over premature optimization
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment