All skills
sergiodxa avatar

/frontend-react-best-practices

@734526d

React performance optimization guidelines. Use when writing, reviewing, or refactoring React components to ensure optimal rendering and bundle patterns. Triggers on tasks involving React components, hooks, memoization, or bundle optimization.

Use this Skill: https://skilld.dev/gh/sergiodxa/agent-skills/frontend-react-best-practices

This session only. Nothing lands on disk.

ruleshooks-useeffect-named-functions.md

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

Name useEffect Functions

Use named function declarations instead of arrow functions in useEffect. Also name cleanup functions.

Why

  1. Stack traces: Named functions appear in error stack traces, making debugging easier
  2. Self-documentation: The function name explains what the effect does
  3. Single responsibility: Naming encourages one concern per effect
  4. Code review: Easier to understand effect purpose at a glance

Bad: Anonymous Arrow Functions

// Bad: anonymous functions hide intent
useEffect(() => {
  document.title = title;
}, [title]);

useEffect(() => {
  let handler = (e: KeyboardEvent) => {
    if (e.key === "Escape") onClose();
  };
  window.addEventListener("keydown", handler);
  return () => window.removeEventListener("keydown", handler);
}, [onClose]);

When these effects error, the stack trace shows anonymous or <anonymous>.

Good: Named Function Declarations

// Good: named functions are self-documenting
useEffect(
  function syncDocumentTitle() {
    document.title = title;
  },
  [title],
);

useEffect(
  function handleEscapeKey() {
    let handler = (e: KeyboardEvent) => {
      if (e.key === "Escape") onClose();
    };
    window.addEventListener("keydown", handler);

    return function removeEscapeKeyHandler() {
      window.removeEventListener("keydown", handler);
    };
  },
  [onClose],
);

Stack traces now show syncDocumentTitle or handleEscapeKey.

Pattern Examples

Data Synchronization

useEffect(
  function syncLocalStorage() {
    localStorage.setItem("preferences", JSON.stringify(preferences));
  },
  [preferences],
);

Subscriptions

useEffect(function subscribeToOnlineStatus() {
  function handleOnline() {
    setIsOnline(true);
  }
  function handleOffline() {
    setIsOnline(false);
  }

  window.addEventListener("online", handleOnline);
  window.addEventListener("offline", handleOffline);

  return function unsubscribeFromOnlineStatus() {
    window.removeEventListener("online", handleOnline);
    window.removeEventListener("offline", handleOffline);
  };
}, []);

Form Reset (Remix pattern)

useEffect(
  function resetFormOnSuccess() {
    if (fetcher.state === "idle" && fetcher.data?.ok) {
      formRef.current?.reset();
    }
  },
  [fetcher.state, fetcher.data],
);

Third-Party Integration

useEffect(function initializeMap() {
  if (!mapRef.current) return;

  let map = new MapLibrary(mapRef.current, { center });
  mapInstanceRef.current = map;

  return function destroyMap() {
    map.destroy();
  };
}, []);

Analytics

useEffect(
  function trackPageView() {
    analytics.page(pathname);
  },
  [pathname],
);

Naming Conventions

Effect Purpose Name Pattern
Sync data sync[What] - syncDocumentTitle, syncLocalStorage
Subscribe subscribeTo[What] - subscribeToOnlineStatus
Initialize initialize[What] - initializeMap, initializeChart
Handle event handle[What] - handleEscapeKey, handleResize
Track/log track[What] - trackPageView, logError
Reset reset[What] - resetFormOnSuccess
Cleanup destroy[What], remove[What], unsubscribeFrom[What]

Multiple Effects

Named functions make it clear why you have separate effects:

function UserProfile({ userId }: Props) {
  useEffect(
    function fetchUserData() {
      // Fetch user when userId changes
    },
    [userId],
  );

  useEffect(
    function trackProfileView() {
      // Analytics - separate concern
      analytics.track("profile_viewed", { userId });
    },
    [userId],
  );

  useEffect(function setupKeyboardShortcuts() {
    // Keyboard handling - separate concern
  }, []);
}

Rules

  1. Always use named function declarations in useEffect, not arrow functions
  2. Name cleanup functions too (return function cleanup() { ... })
  3. Use descriptive names that explain the effect's purpose
  4. One concern per effect - if you can't name it clearly, split it
  5. Follow naming conventions: sync*, subscribeTo*, initialize*, handle*, track*

Source: SKILL.md on GitHub

1 warning16d5 checks · Risk SAFE
  • Gen Agent Trust Hub16d

    This skill is a collection of React performance and composition guidelines. It contains no executable code, scripts, or malicious patterns and is entirely informational.

  • Socket16d

    No alerts

  • Snyk16d

    Risk: LOW · No issues

  • Runlayer7mo

    37/37 files flagged

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at 734526d. 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.

Dormantupdated 8 months ago

README badge

README badge for sergiodxa/agent-skills/frontend-react-best-practices