0Pricing
React Academy · Урок

forwardRef: предоставление родителям доступа к ссылкам DOM

Узнайте, как forwardRef позволяет родительским компонентам получать доступ к узлу DOM или экземпляру дочернего компонента.

«forwardRef: предоставление родителям доступа к ссылкам DOM» — бесплатный урок React Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения React Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс React Academy содержит 4 уроков всего.

Что такое ссылки ref и в чём их ограничение по умолчанию

Ссылка ref — это способ хранить ссылку на узел DOM или экземпляр компонента, которая сохраняется между отрисовками, не вызывая повторных отрисовок. Вы указываете её с помощью атрибута ref, а React заполняет её свойство current после фиксации изменений в DOM.

Проблема в том, что нельзя прикрепить ref к функциональному компоненту так же, как к div. По умолчанию у родителя нет способа обратиться к узлу DOM, находящемуся внутри дочернего компонента, потому что ссылки не передаются подобно обычным свойствам.

Обёртка forwardRef для компонента

React.forwardRef позволяет компоненту получить ref от родителя и передать его дальше одному из собственных элементов. Он оборачивает функцию компонента и изменяет её сигнатуру так, что ref приходит вторым аргументом вместе со свойствами.

Это официальный способ обойти ограничение и предоставить вызывающему компоненту доступ к внутреннему узлу DOM, превратив в остальном непрозрачный дочерний компонент в такой, на элемент которого родитель может ссылаться напрямую.

Сигнатура forwardRef

Обернутая функция принимает два параметра: (props, ref). Первый — обычный объект свойств, а второй — переданная дальше ссылка ref. Затем эту ссылку распределяют по элементу или прикрепляют к нему, чтобы предоставить к нему доступ, например задавая ref={ref} для внутреннего поля ввода.

Помните, что только компоненты, обёрнутые в forwardRef, получают этот второй аргумент. Обычный функциональный компонент, в котором ref указан вторым параметром, просто получит значение undefined.

Пример: фокусировка дочернего поля ввода из родителя

Классический пример — повторно используемый компонент текстового поля, внутреннее поле ввода которого должен сфокусировать родитель. Обернув поле в forwardRef и прикрепив переданную дальше ссылку ref к исходному элементу поля ввода, родитель может напрямую вызвать у него focus().

Так компонент поля остаётся повторно используемым, а управляемый императивный доступ предоставляется именно там, где он нужен, например для фокусировки первого поля формы при монтировании.

Измерение дочернего элемента

Переданные дальше ссылки ref также позволяют выполнять измерения. Родитель может прочитать offsetWidth, offsetHeight или вызвать getBoundingClientRect у дочернего элемента, полученного через forwardRef.

Это полезно для всплывающих подсказок, всплывающих окон и расчётов макета, когда родителю нужно знать точный отображаемый размер или положение внутреннего элемента, прежде чем решить, как разместить что-либо относительно него.

Вызов методов прокрутки

Поскольку переданная дальше ссылка ref указывает на настоящий узел DOM, родитель может вызывать у него встроенные методы DOM. Вызов scrollIntoView у переданного дальше элемента списка плавно прокручивает страницу к нему, а scrollTo у переданного дальше контейнера прокрутки изменяет положение его содержимого.

Это императивные действия, для которых нет удобного декларативного эквивалента, — именно для таких взаимодействий и предназначены ссылки ref.

Передача ref через несколько уровней

Иногда элемент, который нужно предоставить наружу, находится на несколько компонентов глубже. Можно объединить несколько вызовов forwardRef в цепочку: каждый промежуточный уровень передаёт полученную ссылку ref следующему, пока она наконец не окажется на целевом узле DOM.

Каждая обёртка в цепочке сама должна использовать forwardRef и передавать ссылку ref дальше, поскольку обычный компонент в середине разорвал бы это соединение.

Композиция forwardRef + memo

forwardRef и React.memo можно объединить, чтобы получить и передачу ссылок ref, и мемоизацию отрисовки. Обычно используется порядок memo(forwardRef(Component)): результат forwardRef оборачивается в memo, поэтому сравнение memo по-прежнему применяется.

Этот шаблон встречается в системах проектирования, чувствительных к производительности, где часто отображаемый компонент должен предоставлять доступ к своему узлу и пропускать ненужные повторные отрисовки.

Просмотр forwardRef в DevTools

В React DevTools компонент forwardRef отображается с меткой ForwardRef, оборачивающей имя вашего компонента. Благодаря этому легко сразу убедиться, что компонент участвует в передаче ссылок ref.

Можно присвоить внутренней функции имя или задать displayName, чтобы запись в DevTools была понятнее, чем обычная анонимная метка ForwardRef.

Когда НЕ (NOT) следует использовать forwardRef

forwardRef предназначен для предоставления доступа к узлам DOM и императивным дескрипторам, а не для передачи данных. Если родителю нужно повлиять на дочерний компонент, предпочтительнее использовать обычные свойства и состояние, а не обращаться внутрь через ссылку ref.

Чрезмерное использование ссылок ref создаёт тесную связанность компонентов и обходит поток данных React, из-за чего за поведением становится сложнее следить. Используйте forwardRef только тогда, когда декларативное свойство действительно не может выразить нужное взаимодействие.

forwardRef в современном React

forwardRef остаётся стандартным инструментом для предоставления ссылок ref в библиотеках компонентов и повторно используемых полях ввода. В новых версиях React развивается подход, при котором ref можно передавать как обычное свойство, но forwardRef по-прежнему широко используется и важен для понимания.

Хорошее знание этого инструмента подготовит вас и к работе с существующими кодовыми базами, и к пониманию базовой механики, на которой будет основан любой будущий синтаксис передачи ref как свойства.

Быстрая проверка: сигнатура forwardRef

Проверьте, насколько хорошо вы понимаете, как компонент с forwardRef получает свою ссылку ref.

Итоги: forwardRef

forwardRef устраняет ограничение, из-за которого родитель не может обратиться к узлу DOM дочернего компонента: компонент получает второй аргумент ref и может передать его внутреннему элементу. Это позволяет фокусировать, измерять и прокручивать дочерние элементы.

forwardRef можно объединять с memo и передавать через несколько уровней; в DevTools он отображается как ForwardRef. Используйте его для императивного доступа к DOM, а не для передачи данных — с этим лучше справляются свойства.

Часто задаваемые вопросы

Урок «forwardRef: предоставление родителям доступа к ссылкам DOM» бесплатный?

Да — полный текст урока «forwardRef: предоставление родителям доступа к ссылкам DOM» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс React Academy, подпишись на CoddyKit PRO. Курс React Academy содержит 4 уроков всего.

Чему я научусь в уроке «forwardRef: предоставление родителям доступа к ссылкам DOM»?

Узнайте, как forwardRef позволяет родительским компонентам получать доступ к узлу DOM или экземпляру дочернего компонента. Ты практикуешь React Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать React Academy?

Предыдущий опыт не требуется. React Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.

Сколько времени занимает урок «forwardRef: предоставление родителям доступа к ссылкам DOM»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке React Academy?

Да. Каждый урок React Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. forwardRef: предоставление родителям доступа к ссылкам DOM
  2. useImperativeHandle: пользовательские значения экземпляра
  3. Создание императивного API компонента
  4. Когда использовать императивные и декларативные API
← Назад к React Academy