react-usecallback

Use when writing or reviewing useCallback usage in React components. Covers React Compiler impact, when useCallback is justified, and the most common mistake (useCallback without memo).

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "react-usecallback" with this command: npx skills add b4r7x/agent-skills/b4r7x-agent-skills-react-usecallback

React useCallback

Overview

useCallback memoizes function references between renders. In 2026 with React Compiler, manual useCallback is rarely needed — the compiler auto-memoizes. Without the compiler, useCallback only helps when paired with memo() on the child component.

With React Compiler (2025+)

React Compiler 1.0 (Oct 2025) auto-applies memoization at build time. Don't add new useCallback — the compiler handles it better. If memoization is unnecessary, the compiler omits it from output.

Exceptions where manual useCallback is still needed:

  • External libraries not compiled by React Compiler (older react-hook-form, animation libs)
  • Functions used as useEffect dependencies that can't be moved inside the effect
  • Custom hooks exporting functions — wrap in useCallback for stable references
  • Measured performance issues the compiler doesn't fix

Without React Compiler

useCallback only makes sense together with memo() on the child component.

// ❌ useCallback without memo = dead code
function Parent() {
  const handleClick = useCallback(() => {
    console.log('click');
  }, []);
  return <Child onClick={handleClick} />;
  // Child re-renders anyway because Parent re-renders
}

// ✅ useCallback + memo = Child skips re-render
const Child = memo(function Child({ onClick }) {
  return <button onClick={onClick}>Click</button>;
});

function Parent() {
  const handleClick = useCallback(() => {
    console.log('click');
  }, []);
  return <Child onClick={handleClick} />;
  // Child does NOT re-render — handleClick has stable reference
}

Valid Use Cases

1. useEffect dependency

const fetchData = useCallback(async () => {
  const data = await fetch('/api/users');
}, []);

useEffect(() => {
  fetchData();
}, [fetchData]); // stable reference = runs once

2. Custom hook exports

function useCart() {
  const [items, setItems] = useState([]);
  // ✅ Stable references for hook consumers
  const addItem = useCallback((item) => {
    setItems(prev => [...prev, item]);
  }, []);
  return { items, addItem };
}

3. Context provider functions

function AuthProvider({ children }) {
  const [user, setUser] = useState(null);
  const logout = useCallback(() => setUser(null), []);
  const value = useMemo(() => ({ user, logout }), [user, logout]);
  return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
}

Decision

QuestionAnswer
Using React Compiler?Don't add useCallback manually
Passing fn to memo()'d child?✅ useCallback
Function in useEffect deps?✅ useCallback (or move fn inside effect)
Exporting fn from custom hook?✅ useCallback
Event handler without memo on child?❌ Skip — it's dead code

Common Mistake

The most over-used pattern: wrapping every event handler in useCallback "for performance" without memo on the child. The React docs say explicitly: use useCallback only for performance optimization, not as a default way to declare functions.

References

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Automation

improve-prompt

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

humanize-readme

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

human-commit

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

deep-plan

No summary provided by upstream source.

Repository SourceNeeds Review