JAVASCRIPT

Expose Child Component Methods to Parent with useImperativeHandle

Discover how to use React's useImperativeHandle hook to customize the instance value that is exposed to parent components when using a ref, enabling method calls.

import React, { useRef, useImperativeHandle, forwardRef, useState } from 'react';

// Child component that exposes a method
const MyInput = forwardRef((props, ref) => {
  const [value, setValue] = useState('');
  const inputRef = useRef(null);

  useImperativeHandle(ref, () => ({
    // This is what the parent component will access via `ref.current`
    focusInput: () => {
      inputRef.current.focus();
    },
    clearInput: () => {
      setValue('');
      inputRef.current.value = ''; // Direct DOM manipulation for clearing
    },
    getInputValue: () => value,
  }));

  return (
    <input
      ref={inputRef}
      type="text"
      value={value}
      onChange={(e) => setValue(e.target.value)}
      placeholder="Type something..."
      style={{ padding: '8px', marginRight: '10px' }}
    />
  );
});

// Parent component
function ParentComponent() {
  const inputRef = useRef(null);

  const handleFocusClick = () => {
    if (inputRef.current) {
      inputRef.current.focusInput();
    }
  };

  const handleClearClick = () => {
    if (inputRef.current) {
      inputRef.current.clearInput();
    }
  };

  const handleGetValueClick = () => {
    if (inputRef.current) {
      alert('Current input value: ' + inputRef.current.getInputValue());
    }
  };

  return (
    <div style={{ padding: '20px', border: '1px solid #eee' }}>
      <h3>Parent Component</h3>
      <MyInput ref={inputRef} />
      <button onClick={handleFocusClick} style={{ marginRight: '5px' }}>Focus Input</button>
      <button onClick={handleClearClick} style={{ marginRight: '5px' }}>Clear Input</button>
      <button onClick={handleGetValueClick}>Get Value</button>
      <p style={{ marginTop: '10px', fontSize: '0.9em', color: '#666' }}>
        (Input value: {inputRef.current ? inputRef.current.getInputValue() : 'N/A'})
      </p>
    </div>
  );
}

// Usage example:
// function App() {
//   return <ParentComponent />;
// }
How it works: `useImperativeHandle` customizes the instance value that is exposed when a ref is attached to a component. It should be used with `forwardRef`. Instead of the parent getting a direct reference to the child's DOM node (which `useRef` usually provides for native elements), `useImperativeHandle` allows you to define an object with specific methods or properties that the parent can call or access. This pattern is useful for imperative interactions, like triggering a focus or resetting a form, while keeping the child's internal state encapsulated.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs