JAVASCRIPT
Exposing Component Methods with useImperativeHandle and forwardRef
Learn to selectively expose methods or values from a child component to its parent using React's useImperativeHandle hook combined with forwardRef.
import React, { useRef, useImperativeHandle, forwardRef } from 'react';
// Child component that exposes a focus method
const TextInput = forwardRef(({ placeholder, onFocus }, ref) => {
const inputRef = useRef(null);
useImperativeHandle(ref, () => ({
focus: () => {
inputRef.current.focus();
if (onFocus) onFocus();
},
// You could expose other methods or properties here
alertValue: () => {
alert(`Current value: ${inputRef.current.value}`);
}
}));
return <input ref={inputRef} type="text" placeholder={placeholder} />;
});
// Parent component that uses the child's exposed method
function ParentComponent() {
const textInputRef = useRef(null);
const handleFocusClick = () => {
if (textInputRef.current) {
textInputRef.current.focus(); // Calls the exposed focus method
}
};
const handleAlertClick = () => {
if (textInputRef.current) {
textInputRef.current.alertValue(); // Calls another exposed method
}
};
return (
<div>
<TextInput ref={textInputRef} placeholder="Enter text here" />
<button onClick={handleFocusClick}>Focus Input</button>
<button onClick={handleAlertClick}>Show Value</button>
</div>
);
}
export default ParentComponent;
How it works: `useImperativeHandle` is used in conjunction with `forwardRef` to customize the instance value that is exposed to parent components when they use a `ref` on a child component. Instead of giving the parent direct access to the child's DOM node or full instance, `useImperativeHandle` allows you to expose a specific set of methods, properties, or an entirely custom value. This pattern is useful for library components or when tightly coupled parent-child interaction is necessary, but you want to keep the child's internal implementation details encapsulated.