We would use useImperativeHandle when
- we want to customize the interface exposed by a child component’s ref to its parent component.
- we need to abstract away complex internal functionality, exposing only essential methods or properties.
- we aimed to optimize performance by selectively exposing imperative methods or properties, reducing unnecessary re-renders triggered by changes irrelevant to the parent component.
- we want to refine access to imperative methods or properties, ensuring controlled interaction between parent and child components.
Example: Below is an example of useImprativeHandle hooks usage.
Javascript
import React, { useRef, useImperativeHandle, forwardRef } from 'react' ; // Child component const ChildComponent = forwardRef((props, ref) => { const internalRef = useRef( null ); // used useImperativeHandle here useImperativeHandle(ref, () => ({ focus: () => { internalRef.current.focus(); }, getValue: () => { return internalRef.current.value; } })); return <input ref={internalRef} />; }); // Parent component const ParentComponent = () => { const childRef = useRef( null ); const handleClick = () => { childRef.current.focus(); }; const handleGetValue = () => { const value = childRef.current.getValue(); console.log(value); }; return ( <div> <ChildComponent ref={childRef} /> <button onClick={handleClick}>Focus Input</button> <button onClick={handleGetValue}>Get Value</button> </div> ); }; export default ParentComponent; |
Output:
What does useImperativeHandle do, and when do we use it?
useImperativeHandle
is a hook provided by React that allows you to customize the instance value that is exposed when a parent component calls ref
on a child component. When you use ref
to get access to a child component, normally you would get the entire instance of that component. But sometimes you might not want the parent to have access to everything inside the child component, just specific functions or values.