useImperativeHandle hook in React

useImperativeHandle hook in React

Β·

2 min read

Table of contents

No heading

No headings in the article.

Certainly! useImperativeHandle is a hook that allows you to expose a custom interface from a child component to its parent component. It's often used in conjunction with forwardRef to create reusable components that allow the parent to control some of their behavior.

In below code, the useImperativeHandle hook is used to expose two functions, focusInput and focusSearchButton, to the parent component. These functions can be used by the parent component to focus on the input field and search button, respectively.

Here’s the code that uses useImperativeHandle:

import { useRef } from "react";
import Input from "./components/Input";

export default function App() {
  const ref= useRef<any>();
  return (
    <div className="App">
      <Input ref={ref} />
      <button onClick={() => ref?.current?.focusInput()}>
        focus input
      </button>
      <button onClick={() => ref?.current?.focusSearchButton()}>
        focus button
      </button>
    </div>
  );
}
import {
  ChangeEvent,
  Ref,
  forwardRef,
  useImperativeHandle,
  useRef,
  useState,
} from "react";

interface InputProps {
  onChange: (e: ChangeEvent<HTMLInputElement>) => void;
  value: string;
  style: object;
}

function Input(props: Partial<InputProps>, ref: Ref<unknown>) {
  const inputref = useRef<HTMLInputElement>(null);
  const buttonRef = useRef<HTMLButtonElement>(null);
  const [val, setVal] = useState<string>(props.value ?? "");
  function handleChange(e: ChangeEvent<HTMLInputElement>) {
    props.onChange && props.onChange(e);
    setVal(e.target.value);
  }
  useImperativeHandle(
    ref,
    () => {
      return {
        focusInput() {
          inputref.current?.focus();
        },
        focusSearchButton() {
          buttonRef.current?.focus();
        },
      };
    },
    []
  );
  return (
    <>
      <input
        ref={inputref}
        placeholder="Enter text"
        onChange={handleChange}
        value={val}
        style={ ...props.style }
      />
      <button ref={buttonRef}>search</button>
    </>
  );
}

export default forwardRef(Input);

The useImperativeHandle hook takes three arguments: the ref object that was passed from the parent component, a function that returns an object with the functions you want to expose, and an array of dependencies.

The function passed as the second argument returns an object with two functions, focusInput and focusSearchButton, which can be called by the parent component to focus on the input field and search button, respectively. These functions use the current property of the input and button references created earlier to access their DOM elements and call the focus method on them.

The empty array passed as the third argument tells React that there are no dependencies for this useImperativeHandle hook, so it will only run once when the component is mounted.

Overall, useImperativeHandle is a powerful hook that can be used to create flexible and reusable components. By exposing a custom interface, you can give the parent component control over specific aspects of the child component's behavior, making it easier to integrate into different parts of your application.

Β