React: для чого потрібен хук useImperativeHandle

Хук useImperativeHandle в React призначений для експорту певних функцій компоненту-контейнеру, які можуть бути викликані зовнішнім кодом. В основному, він використовується в компонентах, які реалізують інтерфейс ref.

Зазвичай, коли ви створюєте ref для компонента, ви можете звернутися до методів компонента через ref.current, але іноді може знадобитися отримати прямий доступ до цих методів, зокрема, коли потрібно передати їх як пропси до дочірніх компонентів.

Використовуючи useImperativeHandle, ви можете задати, які методи мають бути доступні через ref, тим самим визначаючи інтерфейс компонента для зовнішнього світу. Це дає більшу контроль над тим, як ваш компонент взаємодіє з зовнішнім кодом та зменшує кількість випадків, коли потрібно звертатися до ref.current.

Зауважте, що використання useImperativeHandle рідко потрібне і має сенс тільки тоді, коли вам потрібен прямий доступ до методів компонента ззовні. Нижче я наведу простий приклад використання useImperativeHandle, який показує, як він може бути використаний для експорту функцій з компонента.

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

// Компонент, який ми хочемо експортувати методи з
const Input = (props, ref) => {
  const [value, setValue] = useState('');

  // Метод для очищення поля вводу
  const clearInput = () => {
    setValue('');
  };

  // Використовуємо useImperativeHandle для експорту clearInput методу
  useImperativeHandle(ref, () => ({
    clearInput: () => clearInput()
  }));

  return (
    <input type="text" value={value} onChange={e => setValue(e.target.value)} />
  );
};

// Передаємо Input компонент як forwardRef
const ForwardedInput = forwardRef(Input);

// Використовуємо експортований метод clearInput з рефа
const App = () => {
  const inputRef = useRef(null);

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

  return (
    <>
      <ForwardedInput ref={inputRef} />
      <button onClick={handleButtonClick}>Очистити поле вводу</button>
    </>
  );
};

У цьому прикладі ми створили компонент Input, який має метод clearInput, який очищає поле вводу. Ми використали useImperativeHandle, щоб експортувати цей метод через ref, який ми передали в компонент.

Далі, ми передали Input компонент через forwardRef, щоб отримати доступ до рефа з App компонента. Ми використали цей реф, щоб викликати метод clearInput, коли користувач натисне кнопку. Таким чином, ми могли звернутися до методу clearInput ззовні Input компонента, що зробило його більш гнучким і перевикористовуваним.