Зарегистрируйтесь для доступа к 15+ бесплатным курсам по программированию с тренажером

Refs JS: React

React по своей природе изолирует вас от прямой работы с DOM на 100%. Но нередко при интеграции сторонних компонентов, которые написаны не на React, возникает задача на прямой доступ к DOM. Также подобный механизм нужен для выделения текста, фокусов и проигрывания медиа.

React позволяет сделать это с помощью рефов (refs). Важно понимать, что в нормальной ситуации этот механизм не нужен и следует максимально избегать его использования.

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

See the Pen js_react_refs_focus by Hexlet (@hexlet) on CodePen.

ref — это атрибут компонента, значением которого должен быть объект, созданный в конструкторе через функцию React.createRef(). Этот объект, в отличие от остальных данных, которые находятся в props или state, хранится как обычное свойство объекта. Имя свойства можно выбрать произвольно. Свойство current этого объекта даёт доступ к элементу DOM, именно его можно использовать в componentDidMount или componentDidUpdate.

this.<имя свойства>.current хранит внутри себя DOM-элемент того компонента, для которого был установлен ref. В примере выше это input: <input ref={this.textInput} />. DOM-элемент попадает туда (внутрь current) уже после того, как текущий компонент будет встроен в реальный DOM, а значит им можно воспользоваться в указанных выше колбеках componentDidUpdate и componentDidMount.

Ниже приведён пример создания компонента обёртки над популярным jQuery-плагином Chosen.

See the Pen js_react_refs_dom by Hexlet (@hexlet) on CodePen.

Рефы также могут использоваться и на самописных компонентах, реализованных как классы.

Использование в реальном мире

С React удобно и легко работать до тех пор, пока мы остаёмся в рамках самого React, но большая часть существующих JS-библиотек взаимодействует с DOM напрямую, что фактически нивелирует преимущества React при их использовании. Например:

// https://github.com/kylefox/jquery-modal
$('#login-form').modal();

Включение в проект таких библиотек неизбежно приведёт к активному использованию методов жизненного цикла и сделает код сложным. По этой причине принято создавать так называемые компоненты-обёртки (врапперы), которые скрывают внутри себя все взаимодействие с DOM и наружу выставляют стандартный интерфейс React, а именно пропсы. Одной из таких задач, с взаимодействием с DOM, является изменение размера контейнера. Один из вариантов решения — компонент react-resizable. Посмотрите на работу этого компонента:

const Resizable = require('react-resizable').Resizable; // or,
const ResizableBox = require('react-resizable').ResizableBox;

// ES6
import { ResizableBox } from 'react-resizable';

// ...
render() {
  return (
    <ResizableBox width={200} height={200} minConstraints={[100, 100]} maxConstraints={[300, 300]}>
      <span>Contents</span>
    </ResizableBox>
  );
}

Ничего в этом коде не напоминает о реальном DOM. Всё сводится к тому, что компонент оборачивается в ResizableBox, который скрывает всю работу внутри себя. По такому же принципу устроены сотни и, может быть, тысячи других компонентов, которые доступны на GitHub. Вот некоторые из них:

  • react-hotkeys
  • react-stripe-elements (платёжный шлюз)

Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты

Об обучении на Хекслете

Для полного доступа к курсу нужен базовый план

Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
1000
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов
Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff
Рекомендуемые программы
профессия
от 6 300 ₽ в месяц
Разработка фронтенд-компонентов для веб-приложений
10 месяцев
с нуля
Старт 25 апреля
профессия
от 9 900 ₽ в месяц
Разработка фронтенд- и бэкенд-компонентов для веб-приложений
16 месяцев
с нуля
Старт 25 апреля

Используйте Хекслет по-максимуму!

  • Задавайте вопросы по уроку
  • Проверяйте знания в квизах
  • Проходите практику прямо в браузере
  • Отслеживайте свой прогресс

Зарегистрируйтесь или войдите в свой аккаунт

Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»