Home
React
Advanced React APIs: Imperative Handles
June 17, 2025
1 min

Table Of Contents

01
🧠 Basic Idea: Exposing Methods via ref
02
āœ… The Better Way: useImperativeHandle
03
āš ļø When to Use This
04
āœ… Summary

šŸŽÆ Imperative Handles in React 19

In React, we usually build UIs in a declarative way. But sometimes, you may want to imperatively interact with a child component—for example:

  • Focusing an input field
  • Scrolling to the bottom of a container
  • Triggering animations or modals

To do this, React allows you to expose methods from a child component to the parent using a ref. This ref is created with useRef and passed down to the child. Once inside the child, you can attach methods to it.


🧠 Basic Idea: Exposing Methods via ref

type InputAPI = { focusInput: () => void }
function MyInput({
ref,
...props
}: React.InputHTMLAttributes<HTMLInputElement> & {
ref: React.RefObject<InputAPI>
}) {
const inputRef = useRef<HTMLInputElement>(null)
ref.current = {
focusInput: () => inputRef.current?.focus(),
}
return <input ref={inputRef} {...props} />
}
function App() {
const myInputRef = useRef<InputAPI>(null)
return (
<div>
<MyInput ref={myInputRef} placeholder="Enter your name" />
<button onClick={() => myInputRef.current?.focusInput()}>
Focus the input
</button>
</div>
)
}

āœ… This works, but has limitations:

  • āŒ Doesn’t support callback refs
  • āŒ Can break under React’s concurrent rendering
  • āŒ Not ideal with React features like Suspense

āœ… The Better Way: useImperativeHandle

React provides a built-in hook—useImperativeHandle—to safely expose imperative methods. In React 19, you can now access ref directly as a prop, so there’s no need for forwardRef.

type InputAPI = { focusInput: () => void }
function MyInput({
ref,
...props
}: React.InputHTMLAttributes<HTMLInputElement> & {
ref: React.RefObject<InputAPI>
}) {
const inputRef = useRef<HTMLInputElement>(null)
useImperativeHandle(
ref,
() => ({
focusInput: () => inputRef.current?.focus(),
}),
[]
)
return <input ref={inputRef} {...props} />
}

Notice that we passed an empty dependency array to useImperativeHandle. That’s fine—even if you’re using refs inside—because React refs don’t change between renders, so they don’t need to be included in dependencies.

šŸ“˜ Learn more: Why you shouldn’t put refs in a dependency array


āš ļø When to Use This

useImperativeHandle is useful for:

  • DOM interactions (focus, scroll, play, pause, etc.)
  • Custom components exposing actions to their parent
  • Building reusable component libraries

āš ļø But keep in mind: imperative code should be a last resort. It’s harder to test, debug, and reason about. Prefer declarative solutions when possible.

šŸ“– More on that here: Imperative vs Declarative Programming


āœ… Summary

  • useImperativeHandle lets child components expose custom methods to their parent.
  • In React 19, ref can be accessed directly from props, so there’s no need to use forwardRef.
  • Prefer declarative solutions first—but when you need to go imperative, now you can do it cleanly.

Tags

#AdvancedReactAPIs

Share

Related Posts

Advanced React APIs: Sync Exernal Store
Advanced React APIs: Sync Exernal Store
June 19, 2025
2 min
Ā© 2025, All Rights Reserved.
Powered By

Social Media

githublinkedinyoutube