Зачем нужен useImperativeHandle в React
useImperativeHandle
— это хук в React, который позволяет управлять тем, какие методы и свойства будут доступны родителю при использовании ref
на дочернем компоненте.
Он используется в паре с forwardRef
, чтобы настроить внешний интерфейс доступа к внутренним функциям/значениям компонента.
Синтаксис
useImperativeHandle(ref, () => ({
// методы, которые будут доступны извне
someMethod() {
// ...
},
}), [dependencies]);
ref
— ссылка, переданная черезforwardRef
.- Функция
() => ({...})
возвращает объект с публичным API. [dependencies]
— список зависимостей для обновления объекта.
Когда нужен useImperativeHandle
- Когда вы хотите ограничить доступ к внутренним функциям компонента (инкапсуляция).
- Когда нужно экспонировать методы дочернего компонента родителю (например,
focus
,reset
,scrollToTop
и др.). - Когда работаете с нестандартными или сложными DOM-элементами, кастомными компонентами, модальными окнами и т.д.
Пример: доступ к методу focus из родителя
import React, { useRef, useImperativeHandle, forwardRef } from 'react';
const CustomInput = forwardRef((props, ref) => {
const inputRef = useRef<HTMLInputElement>(null);
useImperativeHandle(ref, () => ({
focus: () => {
inputRef.current?.focus();
},
clear: () => {
inputRef.current!.value = '';
}
}));
return <input ref={inputRef} {...props} />;
});
export default function App() {
const inputRef = useRef<{ focus: () => void; clear: () => void }>(null);
return (
<div>
<CustomInput ref={inputRef} />
<button onClick={() => inputRef.current?.focus()}>Фокус</button>
<button onClick={() => inputRef.current?.clear()}>Очистить</button>
</div>
);
}
Важно:
useImperativeHandle
работает только внутри компонентов, обёрнутых в forwardRef
.
Вывод
useImperativeHandle
— это продвинутый инструмент React, который используется в случаях, когда нужно явно настроить интерфейс доступа к компоненту через ref
. Это удобно для создания контролируемых компонентов, модальных окон, кастомных инпутов и других ситуаций, где родителю нужно управлять поведением потомка напрямую.