
No Use Effect
Avoid direct React `useEffect` usage when writing or reviewing React components and hooks.
Install
npx skills add fastrepl/anarlog --skill no-use-effect -g -a claude-code -y- Repository
- fastrepl/anarlog9.7k
- Category
- AI and agents
- Updated
- 3d ago
- License
- MIT
- Context cost
- Lightabout 708 tokens
- Runs scripts
- No, instructions only
What it does
Avoid direct React `useEffect` usage when writing or reviewing React components and hooks. Use this skill when creating new React code, refactoring existing `useEffect` calls, reviewing PRs that introduce `useEffect`, or when an agent reaches for `useEffect` as a default. Replace effects with derived state, query or mutation libraries, event handlers, `useMountEffect` for mount-only external sync, or `key`-based remounts.
No useEffect
Never call useEffect directly unless the work is a true mount-only sync with an external system and no simpler pattern fits. Prefer a render-time computation, a query or mutation hook, an event handler, or a remount boundary instead.
Workflow
- Classify why the effect exists.
- Replace it with the narrowest pattern below.
- Verify with the project's normal lint, typecheck, and tests.
Replacement Patterns
1. Derive state, do not sync it
Replace useEffect(() => setX(derive(y)), [y]) with inline computation or the project's existing memoization conventions.
const filteredProducts = products.filter((product) => product.inStock);
Smell test: state only mirrors props or other state.
2. Use query or mutation libraries for async work
Replace fetch-in-effect code with the app's data layer.
const productQuery = useQuery({
queryKey: ["product", productId],
queryFn: () => fetchProduct(productId),
});
Smell test: the effect fetches, awaits, retries, cancels, or writes async results into local state.
3. Use event handlers for user actions
Do the work where the action happens instead of setting a flag and reacting later.
const handleLike = () => {
postLike();
};
Smell test: state exists only to trigger an effect, then gets reset.
4. Use useMountEffect for mount-only external sync
Use this only for work that is naturally "set up on mount, clean up on unmount": DOM integration, subscriptions, third-party widgets, and stable singleton bindings.
If the project already has a useMountEffect, use it. If not, add a small wrapper:
import { useEffect } from "react";
export function useMountEffect(effect: () => void | (() => void)) {
useEffect(effect, []);
}
Prefer changing component structure so the component only mounts once preconditions are satisfied.
Smell test: the effect is a one-time setup or teardown for something outside React.

