Разделите проблемы, используя два самых мощных шаблона React.

Render props и пользовательские хуки — это мощные шаблоны повторного использования в React.

В этой статье я покажу вам, как разделить проблемы с помощью простого свойства рендеринга, похожего на тот, что в документации React, используя хуки useState и useEffect. Затем я покажу вам, как реализовать собственный хук, чтобы сделать ваш код еще более пригодным для повторного использования.

Использование реквизита рендеринга

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

Когда вы перемещаете мышь в окне, приложение дважды отображает координаты мыши, один раз с элементами списка, где верхний элемент — это координата X, а нижний элемент — координата Y; и один раз внутри элемента ‹h3›.

Я дважды визуализирую координаты мыши, чтобы проиллюстрировать полезность шаблона render prop: вы можете использовать один и тот же компонент, производящий данные, для рендеринга данных компонента, как вам нравится, с помощью функции prop .

Вот реализация приложения. Он использует компонент MouseTracker, который реализует шаблон поддержки рендеринга.

Приложение передает свойство рендеринга — функцию, которая принимает данные от компонента и возвращает JSX — в MouseTracker. Компонент, в данном случае MouseTracker, подготавливает данные, а свойство рендеринга выполняет рендеринг. Это разделение интересов и есть суть реквизита для рендеринга.

Реализация Render Prop

Вот компонент MouseTracker, реализованный с помощью useState и useEffect.

React выполняет функцию, переданную в useEffect(), после первого рендеринга компонента, а затем выполняет функцию, возвращенную useEffect(), когда компонент размонтируется. Эти две функции добавляют и удаляют прослушиватель событий mousemove в окно и из него соответственно.

Когда пользователь перемещает мышь, прослушиватель событий обновляет координаты мыши, вызывая функцию setMouseLocation(), возвращаемую функцией useState(). Это обновление состояния вызывает повторную визуализацию MouseTracker. Повторный рендеринг вызывает свойство рендеринга, передавая обновленные координаты мыши.

Реквизиты рендеринга не обязательно должны называться рендер. Это имя просто условность. Вы можете называть реквизиты рендеринга как угодно.

Свойство рендеринга также может быть неявным дочерним свойством, и в этом случае вы вообще не даете ему имя. Вот как вы могли бы использовать MouseTracker с дочерними элементами в качестве реквизита рендеринга.

А вот и обновленная реализация MouseTracker (единственное отличие от предыдущей реализации — использование дочерней опоры в строке 14).

Реализация пользовательского хука

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

Хуки — это функции, поэтому мы можем извлекать их вызовы в собственные функции. И эти объемлющие функции могут принимать аргументы и возвращать значение.

В предыдущем листинге я извлек хуки, использовавшиеся в исходной версии MouseTracker, в пользовательский хук: функцию useMouse(), которая возвращает координаты окна для последней позиции мыши.

В предыдущем листинге есть два интересных момента. Во-первых, он импортирует useState и useEffect, но не импортирует React. Причина, по которой он не импортирует React, заключается в том, что он не создает никакого JSX.

Во-вторых, имя функции начинается с use. Это важно, но не обязательно, чтобы правила lint, поставляемые с create-react-app, могли гарантировать, что функция следует Правилам хуков.

Наконец, вот обновленная реализация MouseTracker (строки 4–7).

Использование пользовательского хука useMouse() сокращает реализацию MouseTracker всего до двух строк кода. Пользовательский хук useMouse() также можно импортировать и использовать другими функциональными компонентами React, которым необходимо отслеживать координаты мыши.

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

Вывод

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

Пользовательские хуки позволяют вам еще больше разделить проблемы, создавая многократно используемые хуки, которые могут использоваться другими функциональными компонентами React.