Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як типізувати useRef для DOM-елемента і для значення, що зберігається між рендерами?

useRef має два різні призначення, і з TypeScript це видно в типах.

1. Посилання на DOM-елемент:

const inputRef = useRef<HTMLInputElement>(null);
// тип: RefObject<HTMLInputElement | null>

useEffect(() => {
  inputRef.current?.focus();   // до монтування - null, тому ?.
}, []);

return <input ref={inputRef} />;

Тип елемента - відповідний клас DOM: HTMLInputElement, HTMLDivElement, HTMLCanvasElement. Якщо вказати не той (HTMLDivElement для <input>), TypeScript повідомить про помилку в атрибуті ref.

2. Змінне значення, що не викликає рендер:

const timerId = useRef<number | null>(null);
const renders = useRef(0);   // RefObject<number>, тип виведено

function start() {
  timerId.current = window.setInterval(tick, 1000);
}

Що змінилося в типах React 19:

  • useRef вимагає аргумент. useRef<number>() без початкового значення - помилка компіляції; треба явно useRef<number | undefined>(undefined);
  • current завжди можна змінювати. Раніше useRef<T>(null) повертав RefObject з current лише для читання, а useRef<T>(initial) - MutableRefObject, і плутанина між ними давала незрозумілі помилки. Тепер є один RefObject<T> зі змінним current;
  • MutableRefObject оголошено застарілим.

window.setInterval, а не setInterval: у проєктах, де є і типи DOM, і типи Node.js, глобальний setInterval повертає NodeJS.Timeout, а не число. Явний window. прибирає конфлікт, або тип ref - ReturnType<typeof setInterval>.

Колбек-ref з очищенням (React 19):

<div ref={(node) => {
  if (!node) return;
  const observer = new ResizeObserver(onResize);
  observer.observe(node);
  return () => observer.disconnect();   // функція очищення
}} />

У TypeScript колбек-ref тепер не може неявно повертати значення: ref={(node) => (instance = node)} - помилка, бо присвоєння повертає значення, яке React вважав би функцією очищення. Потрібні фігурні дужки.

Правило з документації: не читати й не змінювати ref.current під час рендеру (крім лінивої ініціалізації) - лише в обробниках подій та ефектах.

Докладніше в документації: useRef

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання