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-limit-useeffect.md

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

Limit useEffect Usage

Use useEffect only when absolutely necessary. Prefer derived state, event handlers, or other patterns.

Why

  1. Effects are escape hatches - For synchronizing with external systems, not for React logic
  2. Common source of bugs - Missing dependencies, infinite loops, stale closures
  3. Performance overhead - Runs after render, can cause extra re-renders
  4. Usually unnecessary - Most "effects" are better expressed differently

When NOT to Use useEffect

Deriving State from Props/State
// Bad: useEffect to derive state
function FilteredList({ items, query }: Props) {
  let [filtered, setFiltered] = useState(items);

  useEffect(() => {
    setFiltered(items.filter((item) => item.name.includes(query)));
  }, [items, query]);

  return <List items={filtered} />;
}

// Good: derive during render
function FilteredList({ items, query }: Props) {
  let filtered = items.filter((item) => item.name.includes(query));
  return <List items={filtered} />;
}

// Good: useMemo if expensive
function FilteredList({ items, query }: Props) {
  let filtered = useMemo(
    () => items.filter((item) => item.name.includes(query)),
    [items, query],
  );
  return <List items={filtered} />;
}
Responding to Events
// Bad: useEffect to handle form submission result
function Form() {
  let [submitted, setSubmitted] = useState(false);

  useEffect(() => {
    if (submitted) {
      showToast("Submitted!");
      navigate("/success");
    }
  }, [submitted]);

  return <form onSubmit={() => setSubmitted(true)}>...</form>;
}

// Good: handle in event handler
function Form() {
  function handleSubmit() {
    // Do it directly in the handler
    showToast("Submitted!");
    navigate("/success");
  }

  return <form onSubmit={handleSubmit}>...</form>;
}
Resetting State on Prop Change
// Bad: useEffect to reset state
function UserProfile({ userId }: Props) {
  let [user, setUser] = useState(null);

  useEffect(() => {
    setUser(null); // Reset when userId changes
  }, [userId]);
}

// Good: use key to reset component
<UserProfile key={userId} userId={userId} />;
Transforming Data for Render
// Bad: useEffect to transform
function Chart({ data }: Props) {
  let [chartData, setChartData] = useState([]);

  useEffect(() => {
    setChartData(data.map((d) => ({ x: d.date, y: d.value })));
  }, [data]);
}

// Good: transform during render
function Chart({ data }: Props) {
  let chartData = data.map((d) => ({ x: d.date, y: d.value }));
  return <LineChart data={chartData} />;
}

When to Use useEffect

Synchronizing with External Systems
// Good: subscribing to browser APIs
function useOnlineStatus() {
  let [isOnline, setIsOnline] = useState(navigator.onLine);

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

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

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

  return isOnline;
}
Connecting to Third-Party Libraries
// Good: integrating with non-React code
function Map({ center }: Props) {
  let mapRef = useRef<HTMLDivElement>(null);
  let mapInstance = useRef<MapLibrary | null>(null);

  useEffect(() => {
    if (!mapRef.current) return;

    mapInstance.current = new MapLibrary(mapRef.current, { center });

    return () => {
      mapInstance.current?.destroy();
    };
  }, []);

  // Update map when center changes
  useEffect(() => {
    mapInstance.current?.setCenter(center);
  }, [center]);

  return <div ref={mapRef} />;
}
Analytics/Logging (fire and forget)
// Good: logging page views
useEffect(() => {
  analytics.logPageView(pathname);
}, [pathname]);

Summary

Scenario Use Instead
Derive state from props Calculate during render
Expensive calculation useMemo
Respond to user action Event handler
Reset state on prop change key prop
Transform data Calculate during render
Subscribe to external system useEffect (correct use)
Connect to third-party lib useEffect (correct use)

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