Écrire des Effects React optimisés

VérifiéSûr

Guide l'écriture de composants React en évitant les appels inutiles à useEffect. Utile lors de la création ou la révision de composants, du refactoring d'effets, ou lorsque le code utilise useEffect pour transformer des données ou gérer des événements au lieu de synchroniser avec des systèmes externes.

Spar Skills Guide Bot
DeveloppementIntermédiaire
15002/06/2026
Claude Code
#react#useeffect#refactoring#hooks#anti-patterns

Recommandé pour

Notre avis

Guide pour écrire des composants React en évitant les appels inutiles à useEffect, en utilisant des alternatives comme le calcul pendant le rendu, les gestionnaires d'événements et la prop key.

Points forts

  • Réduit les re-rendus inutiles et les bugs
  • Favorise un flux de données plus propre
  • Apprend un modèle mental pour savoir quand useEffect est vraiment nécessaire
  • Fournit des exemples concrets d'anti-patrons et leurs correctifs

Limites

  • Ne couvre pas les usages avancés comme les hooks personnalisés pour systèmes externes
  • Peut ne pas répondre aux motifs de gestion d'état complexes
  • Se concentre sur React, pas d'autres frameworks
Quand l'utiliser

Utilisez-le lors de l'écriture ou de la révision de composants React pour éliminer les effets inutiles et améliorer les performances.

Quand l'éviter

Ne l'utilisez pas lorsque vous travaillez avec des intégrations de systèmes externes qui nécessitent vraiment useEffect, ou avec du code legacy difficile à refactoriser.

Analyse de sécurité

Sûr
Score qualité90/100

The skill is a purely instructional guide for writing React components without unnecessary useEffect. It contains no executable code, no tool invocations, and no instructions for destructive or exfiltrating actions. There is no risk of misuse.

Aucun point d'attention détecté

Exemples

Refactor useEffect to derived state
I have a React component that uses useEffect to filter a list when props change. How can I refactor it to avoid the effect?
Handle user event without effect
In this component, I'm using useEffect to call onSelect whenever selectedId changes. How can I move this to the event handler instead?
Reset state with key prop
I have a form component that needs to reset all its state when the userId prop changes. Currently I'm using useEffect. What's a better approach?

name: writing-react-effects description: Writes React components without unnecessary useEffect. Use when creating/reviewing React components, refactoring effects, or when code uses useEffect to transform data or handle events. disable-model-invocation: false

Writing React Effects Skill

Guides writing React components that avoid unnecessary useEffect calls.

Core Principle

Effects are an escape hatch for synchronizing with external systems (network, DOM, third-party widgets). If there's no external system, you don't need an Effect.

Decision Flowchart

When you see or write useEffect, ask:

Is this synchronizing with an EXTERNAL system?
├─ YES → useEffect is appropriate
│   Examples: WebSocket, browser API subscription, third-party library
│
└─ NO → Don't use useEffect. Use alternatives:
    │
    ├─ Transforming data for render?
    │   → Calculate during render (inline or useMemo)
    │
    ├─ Handling user event?
    │   → Move logic to event handler
    │
    ├─ Expensive calculation?
    │   → useMemo (not useEffect + setState)
    │
    ├─ Resetting ALL state when prop changes?
    │   → Pass different `key` to component
    │
    ├─ Adjusting SOME state when prop changes?
    │   → Calculate during render or rethink data model
    │
    ├─ Subscribing to external store?
    │   → useSyncExternalStore
    │
    └─ Fetching data?
        → Framework data fetching or custom hook with cleanup

Anti-Patterns to Detect and Fix

| Anti-Pattern | Problem | Alternative | | --------------------------------------------- | -------------------------------------------------------------- | ------------------------------------------ | | useEffect + setState from props/state | Causes extra re-render | Compute during render | | useEffect to filter/sort/transform data | Unnecessary effect cycle | Derive inline or useMemo | | useEffect for click/submit handlers | Loses event context | Event handler | | useEffect to notify parent on state change | Breaks unidirectional data flow | Call parent callback in same event handler | | useEffect with empty deps for one-time init | Runs twice in dev (Strict Mode); conflates app init with mount | Module-level code or didInit ref flag | | useEffect for browser subscriptions | Error-prone manual cleanup | useSyncExternalStore | | useEffect + setState for derived state | Double render, stale intermediate state | Compute value directly during render |

When useEffect IS Appropriate

  • Syncing with external systems (WebSocket connections, third-party widgets, browser APIs)
  • Setting up and cleaning up subscriptions
  • Fetching data based on current props (always include cleanup to handle race conditions)
  • Measuring or imperatively mutating DOM elements after render
  • Integrating with non-React code (jQuery plugins, analytics SDKs, etc.)

Common Refactoring Patterns

Derived state → compute during render

// ❌ Bad
const [filtered, setFiltered] = useState([]);
useEffect(() => {
  setFiltered(items.filter((i) => i.active));
}, [items]);

// ✅ Good
const filtered = items.filter((i) => i.active);
// or with useMemo for expensive operations
const filtered = useMemo(() => items.filter((i) => i.active), [items]);

Notify parent → call in event handler

// ❌ Bad
useEffect(() => {
  onSelect(selectedId);
}, [selectedId]);

// ✅ Good
function handleClick(id) {
  setSelectedId(id);
  onSelect(id);
}

Reset state on prop change → key prop

// ❌ Bad
useEffect(() => {
  setComment("");
}, [userId]);

// ✅ Good — key remounts the component, resetting all state
<ProfileForm key={userId} userId={userId} />;

Data fetching → custom hook with cleanup

// ❌ Bad — no cleanup, race conditions possible
useEffect(() => {
  fetch(`/api/user/${id}`)
    .then((r) => r.json())
    .then(setUser);
}, [id]);

// ✅ Good — cleanup prevents stale responses
useEffect(() => {
  let cancelled = false;
  fetch(`/api/user/${id}`)
    .then((r) => r.json())
    .then((data) => {
      if (!cancelled) setUser(data);
    });
  return () => {
    cancelled = true;
  };
}, [id]);

// ✅ Even better — use a data-fetching library (React Query, SWR, TanStack Query)
const { data: user } = useQuery({
  queryKey: ["user", id],
  queryFn: () => fetchUser(id),
});

Instructions for Claude

When this skill is invoked:

  1. Identify every useEffect call in the provided code
  2. Apply the decision flowchart to each effect individually
  3. Flag anti-patterns from the table above with a clear explanation of the problem
  4. Provide refactored code using the appropriate alternative for each case
  5. Leave legitimate effects untouched — only remove effects that don't belong
  6. When writing new components, never reach for useEffect unless the flowchart confirms it's appropriate

Prioritize correctness over cleverness. A derived value computed inline is always clearer than an effect that syncs it into state.

Skills similaires