Что такое useImperativeHandle в React?

MiddleReact · Frontend·Обновлено 4 августа 2026
Коротко
useImperativeHandle — хук, который позволяет кастомизировать значение ref, передаваемое родительскому компоненту при использовании forwardRef. С его помощью можно ограничить или расширить доступ родителя к DOM-узлу или методам дочернего компонента.

useImperativeHandle

useImperativeHandle используется совместно с forwardRef и позволяет явно контролировать, какие методы или свойства будут доступны через ref для родительского компонента. По умолчанию при передаче ref через forwardRef родитель получает прямой доступ к DOM-узлу дочернего компонента. useImperativeHandle позволяет заменить этот доступ кастомным API.

Сигнатура хука

useImperativeHandle(ref, createHandle, dependencies?);
  • ref — ref, переданный из родителя через forwardRef
  • createHandle — функция, возвращающая объект с методами/свойствами, которые увидит родитель
  • dependencies — массив зависимостей (аналогично useEffect)

Когда применять

Хук нужен, когда компонент хочет предоставить родителю конкретное, ограниченное API, а не весь DOM-узел целиком. Это соответствует принципу инкапсуляции: дочерний компонент контролирует, что именно доступно снаружи.

Типичные сценарии:

  • Модальное окно с методами open() и close()
  • Поле ввода с методами focus() и clear()
  • Анимационный компонент с методом play()

Пример: кастомный инпут

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

interface InputHandle {
  focus: () => void;
  clear: () => void;
}

// Дочерний компонент раскрывает только focus и clear
const CustomInput = forwardRef<InputHandle, React.InputHTMLAttributes<HTMLInputElement>>(
  (props, ref) => {
    const inputRef = useRef<HTMLInputElement>(null);

    useImperativeHandle(ref, () => ({
      focus() {
        inputRef.current?.focus();
      },
      clear() {
        if (inputRef.current) {
          inputRef.current.value = '';
        }
      },
    }));

    return <input ref={inputRef} {...props} />;
  }
);

// Родительский компонент
function Form() {
  const inputRef = useRef<InputHandle>(null);

  const handleReset = () => {
    inputRef.current?.clear();
    inputRef.current?.focus();
  };

  return (
    <div>
      <CustomInput ref={inputRef} placeholder="Введите текст" />
      <button onClick={handleReset}>Сбросить</button>
    </div>
  );
}

Важные нюансы

Зависимости. Если методы в createHandle используют переменные из замыкания, их нужно добавить в массив зависимостей, иначе хук будет работать с устаревшими значениями.

Ограниченность API. Родитель не может обратиться к DOM-узлу напрямую — он видит только то, что вернула createHandle. Это защищает внутреннее устройство компонента.

Не злоупотребляйте. useImperativeHandle нарушает декларативный стиль React. Используйте его только тогда, когда управление через пропсы и состояние неудобно или невозможно (например, для триггерных действий вроде фокуса, скролла, воспроизведения анимации).

Что хочет услышать интервьюер

Кандидат знает, что хук работает только в связке с forwardRef

Понимание цели хука — ограничить доступ родителя к внутреннему DOM и предоставить кастомное API

Знание сигнатуры: три аргумента — ref, createHandle, dependencies

Осознание, что это императивный инструмент и его применение должно быть оправдано

Умение привести конкретный сценарий использования: модалка, input с focus/clear, анимации

Пример: Модальное окно с кастомным API через useImperativeHandle

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

interface ModalHandle {
  open: () => void;
  close: () => void;
}

// Модальное окно раскрывает только open и close
const Modal = forwardRef<ModalHandle>((_, ref) => {
  const [isOpen, setIsOpen] = useState(false);

  useImperativeHandle(ref, () => ({
    open() {
      setIsOpen(true);
    },
    close() {
      setIsOpen(false);
    },
  }));

  if (!isOpen) return null;

  return (
    <div className="modal">
      <p>Содержимое модального окна</p>
    </div>
  );
});

// Родительский компонент управляет модалкой через ref
function App() {
  const modalRef = useRef<ModalHandle>(null);

  return (
    <div>
      <button onClick={() => modalRef.current?.open()}>Открыть</button>
      <button onClick={() => modalRef.current?.close()}>Закрыть</button>
      <Modal ref={modalRef} />
    </div>
  );
}

Типичные ошибки

Путают useImperativeHandle с простым forwardRef — думают, что forwardRef сам по себе достаточен для кастомного API

Забывают указать зависимости, из-за чего методы работают с устаревшими данными из замыкания

Используют хук там, где достаточно пропсов и состояния — это противоречит декларативному подходу React

Не типизируют handle-объект при работе с TypeScript, теряя подсказки и безопасность типов

Применяют хук без forwardRef, что приводит к ошибке в рантайме

Лучшие курсы по теме

изображение курса

TypeScript с нуля

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.8
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Feature-Sliced Design

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.6
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Next.js - с нуля

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее