useRef
Тема дорожной карты · React
useRef — это хук React, возвращающий изменяемый объект ref со свойством .current, сохраняющимся между рендерами и не вызывающим повторный рендер при изменении .current — это идеально для хранения ссылок на DOM-узлы, предыдущих значений состояния, ID интервалов и других императивных дескрипторов. Чаще всего useRef используется для прикрепления ref к DOM-элементу через атрибут ref (<input ref={inputRef} />), давая компонентам React прямой доступ к DOM API для фокусировки, измерения или интеграции с внешними библиотеками. В TypeScript useRef имеет две перегрузки: useRef<T>(initialValue: T) для изменяемых значений и useRef<T>(null) для DOM-refs, где возвращаемый тип RefObject<T> имеет .current только для чтения. В отличие от useState, обновление .current у useRef не планирует повторный рендер React, что делает его правильным инструментом для отслеживания значений, которые должны сохраняться между рендерами, не влияя на вывод. useRef также применяется для управления фокусом, восстановления прокрутки, анимаций и интеграции canvas без накладных расходов на обновление состояния.
Как это работает
useRef использует camelCase event props (onClick, onChange, onSubmit), получающие SyntheticEvent — кроссбраузерную обёртку React над нативным событием. Для форм: "controlled"-компоненты держат значение input в state и ререндерятся на change; "uncontrolled" читают значение через ref при необходимости. useRef возвращает мутируемый контейнер (.current), переживающий рендеры без триггера ререндера — полезно для DOM-узлов и uncontrolled-инпутов.
Когда применять
Controlled-формы — когда (а) нужна валидация по мере ввода, (б) UI зависит от form state (live preview, условные поля), (в) сабмит через fetch с полным контролем. Uncontrolled — когда форма большая + простая (DOM хранит значения, читаете через FormData на сабмит). Для нетривиальных форм — react-hook-form: избегает ререндера на каждое нажатие в полностью controlled-формах.
Типичные ошибки
Ловушки useRef: забытый preventDefault() на сабмите формы — браузер перезагружается; бинд событий на элементах, которые их не генерируют (onClick на <div> без keyboard support = недоступно); хранение каждого нажатия в state на 50-полевой форме (rerender-шторм); использование ref.current внутри render (refs не реактивны — изменения не триггерят ререндер). useRef — escape hatch, не обычный state.