Back to Advanced Patterns

useLatest for Stable Callback Refs

advancedhooksuseLatestrefsoptimization
28.0k🕒 2026-06-10Source ↗

Install this skill

npx skills add vercel-labs/agent-skills

Works across Claude Code, Cursor, Codex, Copilot & Antigravity

The useLatest hook addresses the stale closure problem in React components by maintaining a mutable reference to the most recent version of a value. When passing callbacks as props, those functions often change on every render, triggering unnecessary effect execution. By storing the callback in a ref, you decouple the execution logic from the dependency list. The hook synchronizes the ref's current value with the provided input via an effect, ensuring that the latest logic is always available when the ref is accessed. This strategy keeps effect triggers minimal while preventing outdated state or prop data from influencing asynchronous tasks like timers or event listeners. It serves as an essential pattern for maintaining stable component lifecycles without sacrificing access to current props or state variables during long-running operations.

When to Use This Skill

  • Managing debounced search functions triggered by input changes
  • Handling interval-based telemetry logging that needs the latest user data
  • Triggering callbacks inside event listeners that shouldn't re-bind
  • Maintaining access to latest props during WebSocket message handling

How to Invoke This Skill

Example prompts that trigger this skill in Claude Code, Cursor, or Antigravity:

  • how to stop useEffect from running when my callback prop changes
  • fix stale closure in react timeout
  • create a stable ref for changing props
  • how to get the latest value inside a useEffect without adding to deps
  • prevent unnecessary re-renders when passing functions as props

What this skill does

  • Stores mutable references to current prop values
  • Prevents effect re-runs caused by fluctuating function references
  • Synchronizes internal ref state with every render cycle
  • Provides access to current state within stable intervals
  • Eliminates stale closure bugs in asynchronous logic

When not to use it

  • When the effect actually needs to re-run based on dependency changes
  • When standard state management can solve the synchronization problem naturally

Example workflow

  1. Define the useLatest helper in your project utilities
  2. Identify a component where a useEffect triggers too often due to a callback dependency
  3. Wrap the callback prop inside the useLatest hook
  4. Update the effect dependency array to remove the original callback prop
  5. Reference the .current property of the ref inside your effect logic

Prerequisites

  • Basic understanding of React refs
  • Familiarity with useEffect dependency arrays

Pitfalls & limitations

  • !Requires constant manual access to .current, which can be overlooked
  • !Does not trigger a re-render when the ref value updates
  • !Can hide bugs if overused to bypass proper dependency management

FAQ

Why not just use useCallback?
useCallback creates a new function identity if its dependencies change, which can still trigger effects. useLatest keeps the same ref object identity while updating the logic inside it.
Does this cause re-renders?
No. Changing a ref's current property does not trigger a component re-render.
Can I use this for non-function values?
Yes, it works for any value type that changes frequently but shouldn't trigger an effect.

How it compares

While manual ref management requires boilerplate useEffect calls for every variable, this hook centralizes the logic into a reusable pattern that enforces consistent behavior.

Source & trust

28k stars🕒 Updated 2026-06-10
📄 Full skill instructions — original source: vercel-labs/agent-skills
## useLatest for Stable Callback Refs

Access latest values in callbacks without adding them to dependency arrays. Prevents effect re-runs while avoiding stale closures.

**Implementation:**

function useLatest<T>(value: T) {
const ref = useRef(value)
useEffect(() => {
ref.current = value
}, [value])
return ref
}


**Incorrect (effect re-runs on every callback change):**

function SearchInput({ onSearch }: { onSearch: (q: string) => void }) {
const [query, setQuery] = useState('')

useEffect(() => {
const timeout = setTimeout(() => onSearch(query), 300)
return () => clearTimeout(timeout)
}, [query, onSearch])
}


**Correct (stable effect, fresh callback):**

function SearchInput({ onSearch }: { onSearch: (q: string) => void }) {
const [query, setQuery] = useState('')
const onSearchRef = useLatest(onSearch)

useEffect(() => {
const timeout = setTimeout(() => onSearchRef.current(query), 300)
return () => clearTimeout(timeout)
}, [query])
}

How to Use This Skill Unit

Option A: Project-Specific (Recommended)

  1. Click "Download" above
  2. In your project, create the directory: .agent/skills/advanced-use-latest/
  3. Save the file as SKILL.md
  4. The agent will automatically discover the skill based on its description.

Option B: Global Installation (All Agents)

Save the file to these locations to make it available across all projects:

  • Claude Code: ~/.claude/skills/vercel-labs/agent-skills/advanced-use-latest/SKILL.md
  • Cursor: ~/.cursor/skills/vercel-labs/agent-skills/advanced-use-latest/SKILL.md
  • Antigravity: ~/.gemini/antigravity/skills/vercel-labs/agent-skills/advanced-use-latest/SKILL.md

🚀 Install with CLI:
npx skills add vercel-labs/agent-skills

Read the Master Guide: Mastering Agent Skills

Recommended Rules

View more rules

Recommended Workflows

View more workflows

Recommended MCP Servers

View more MCP servers

Take It Further

Maximize your productivity with these powerful resources

📋

Define Your Standards

Set up coding standards to ensure this workflow produces consistent, high-quality results.

Browse Rules Library
📖

Master Workflows

Learn how to create custom workflows, use Turbo Mode, and build your automation library.

Complete Guide

How to use this Skill in Claude Code & Cursor

For Claude Code (CLI)

To use this skill in Claude Code, copy the rule content into your project's custom instructions or follow our Add-Skill CLI guide. This ensures Claude follows your standards during every code generation.

For Cursor & Windsurf

For Cursor or Windsurf, individual skills are best used in the "Rules for AI" section. This specific unit helps the agent avoid advanced patterns issues, leading to cleaner, more efficient code.

Why the skill format matters: the standardized Agent Skills format lets your AI agent load detailed instructions only when they are relevant, keeping your prompt clean while improving results.

Source & attribution

This skill is categorized under Advanced Patterns and is published by Vercel Engineering, maintained in vercel-labs/agent-skills.

← Browse All Agent Skills
Sponsored AI assistant. Recommendations may be paid.