Skip to main content

Avoid useCallback by Default

Strong preference against useCallback

Source: .agents/rules/no-unnecessary-usecallback.mdc

Metadata

  • alwaysApply: true

Content

Avoid useCallback by Default

  • Prefer plain inline or local functions instead of useCallback in React components.
  • Do not introduce useCallback in new code unless there is a very strong reason.
  • If you think useCallback might help, assume we still don't want it unless:
    • The callback is passed to a memoized child that demonstrably relies on reference stability for correctness or measurable performance, or
    • It is required to prevent an effect's dependency array from causing incorrect re-runs (and this is clearly documented in code comments).
  • When in doubt, do not use useCallback.
// ✅ Preferred: simple function
const onSubmit = async () => {
await save();
};

// ✅ Allowed only with strong justification (document in a comment above)
// Reason: passed to memoized child X that breaks / re-renders excessively without a stable reference.
const onChange = useCallback((value) => {
setValue(value);
}, []);

// ❌ Do not add patterns like this by default
const onClick = useCallback(() => {
doThing();
}, []);