useRef с типами
useRef имеет перегруженные сигнатуры. Тип зависит от того, что ты хранишь.
DOM-элемент
import { useRef } from 'react';
function Form() {
const inputRef = useRef<HTMLInputElement>(null);
return <input ref={inputRef} />;
}
Тип: RefObject<HTMLInputElement> — current равен HTMLInputElement | null.
Почему null? До монтирования DOM-элемента нет.
Использование
inputRef.current?.focus();
inputRef.current?.value;
Или после проверки:
if (inputRef.current) {
inputRef.current.focus();
}
Разные элементы
const divRef = useRef<HTMLDivElement>(null);
const buttonRef = useRef<HTMLButtonElement>(null);
const formRef = useRef<HTMLFormElement>(null);
const videoRef = useRef<HTMLVideoElement>(null);
const canvasRef = useRef<HTMLCanvasElement>(null);
Типы соответствуют элементам:
HTMLDivElementHTMLInputElementHTMLButtonElementHTMLFormElementHTMLSelectElementHTMLTextAreaElementHTMLAnchorElementHTMLImageElementHTMLVideoElementHTMLAudioElementHTMLCanvasElement
Хранение значений
Если нужно хранить значение, не DOM-элемент:
const countRef = useRef(0);
// MutableRefObject<number>
current всегда есть и его можно менять:
countRef.current += 1;
С null инициализацией
const timerRef = useRef<number | null>(null);
Или для любого значения:
const dataRef = useRef<User | null>(null);
Тип RefObject
import type { RefObject } from 'react';
function Input({ ref }: { ref: RefObject<HTMLInputElement | null> }) {
return <input ref={ref} />;
}
Передача ref в компонент
В React 19 ref — обычный пропс:
type InputProps = {
ref?: Ref<HTMLInputElement>;
placeholder?: string;
};
function Input({ ref, placeholder }: InputProps) {
return <input ref={ref} placeholder={placeholder} />;
}
Ref<T> — union RefObject<T> | MutableRefObject<T> | RefCallback<T>.
RefCallback
<input ref={(el) => { /* el: HTMLInputElement | null */ }} />
forwardRef (устаревший)
До React 19:
const Input = forwardRef<HTMLInputElement, InputProps>((props, ref) => {
return <input ref={ref} {...props} />;
});
В React 19 не нужен.
Хранение предыдущего значения
function usePrevious<T>(value: T): T | undefined {
const ref = useRef<T>();
useEffect(() => {
ref.current = value;
}, [value]);
return ref.current;
}
Хранение таймера
const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);
ReturnType<typeof setInterval> — универсальный тип: подходит и для Node, и для браузера.
Хранение функции
const callbackRef = useRef<() => void>(null);
useEffect(() => {
callbackRef.current = () => console.log('click');
});
Итоги
useRef<HTMLInputElement>(null)— для DOMuseRef(0)— для значенияcurrentможет бытьnullRefObject<T>,MutableRefObject<T>,Ref<T>- React 19:
ref— обычный пропс