Коротка відповідь
juniorРеф – це посилання на DOM‑елемент або React‑компонент, що дозволяє безпосередньо взаємодіяти з ним після рендеру. Використовують, коли потрібна фокусування, вимірювання розмірів або доступ до API елемента, що не піддається декларативному опису. У React реф створюють через useRef або createRef, а потім передають у атрибут ref.
Повне пояснення
Реф (reference) – це об’єкт, що зберігає посилання на DOM‑елемент або інстанцію React‑компонента. У функціональних компонентах реф створюють за допомогою хука useRef: const inputRef = useRef(null); і передають у JSX як <input ref={inputRef} />. Після монтуючого циклу inputRef.current містить реальний DOM‑елемент, що дозволяє виконувати операції: inputRef.current.focus(), inputRef.current.getBoundingClientRect() тощо.
Коли використовують реф?
- Фокусування – автозаповнення поля, фокус після відкриття модального вікна.
- Вимірювання – отримання розмірів елемента для анімацій, лейауту.
- Інтеграція з сторонніми бібліотеками – jQuery, D3, Chart.js потребують реального DOM‑елемента.
- Триггеринг анімацій – використання Web Animations API.
- Контроль над скролом – scrollIntoView, scrollTo.
Як працює?
- useRef повертає об’єкт { current: initialValue }.
- При монтуванні React встановлює current на DOM‑елемент.
- Значення зберігається між рендерами, тому не викликає повторного рендеру.
Приклад (React + TypeScript)
import { useRef, useEffect } from 'react';
const FocusInput = () => {
const inputRef = useRef<HTMLInputElement>(null);
useEffect(() => { inputRef.current?.focus(); }, []);
return <input ref={inputRef} />;
};
Тестування – у Jest можна перевірити, що ref отримав DOM‑елемент:
const { getByTestId } = render(<FocusInput data-testid="input" />);
expect(getByTestId('input')).toBeInTheDocument();
Переваги та недоліки
- Перевага: прямий доступ, простота.
- Недолік: порушує декларативність, ускладнює SSR (Server‑Side Rendering) – реф не існує на сервері.
Альтернативи
- Для фокусування можна використовувати useEffect з атрибутом autoFocus.
- Для вимірювання – бібліотека ResizeObserver.
Часті помилки
- Використання ref у функціональних компонентах без useRef → undefined.
- Доступ до current перед монтуючим циклом → null.
- Зміна ref у render‑циклі → перерисування.
- Неочікуваний тип – використання React.RefObject замість HTMLInputElement.
- Застосування ref до компоненту, що не підтримує forwardRef → undefined.
- Залишення ref у state → непотрібний рендер.
- Використання useRef для зберігання значень, що змінюються → не реактивно.
- Неочікуваний re‑render через зміни ref → непотрібна продуктивність.
Короткий чек‑ліст
- Чи потрібен прямий доступ до DOM? → реф.
- Чи можна обійтись декларативно? → не реф.
- Чи працює компонент у SSR? → уникати реф.