Если вы не играли с React Hooks, вам определенно стоит потратить некоторое время, чтобы изучить концепцию и поиграть с ними.

Итак, предположим, что вы уже знаете, что такое React Hooks. Я хочу показать, как можно заменить React HOC на собственный React Hook.

Да, мы собираемся рассмотреть некоторые хуки React, но мы также создадим собственный, так что возьмите кофе и приготовьтесь к этому выпуску.

Наш HOC подлежит замене

Мы возьмем пример HOC из документации React, если вы его не видели, проверьте.

Это подпись HOC:

function withSubscription(WrappedComponent, selectData)

Краткое описание HOC (если вы знаете, что он делает, можете пропустить этот раздел)

Итак, что withSubscription будет делать, так это:

  1. Оберните другой компонент (WrappedComponent)
  2. Добавьте к нему логику (selectData)

Почему ты бы так поступил? Это стратегия, позволяющая разделять общую логику между компонентами. Функция withSubscription (HOC) создаст совершенно новый компонент (это важно понимать), где она будет использовать параметр selectData для выбора некоторых данные откуда-то, и он внедрит эти данные как свойство для WrappedComponent.

Таким образом, всякий раз, когда изменяются базовые данные, он обновляет состояние компонента, созданного функцией withSubscription, и автоматически обновляет WrappedComponent.

Как вы используете этот HOC, как указано в документации:

const CommentListWithSubscription = withSubscription(
  CommentList,
  (DataSource) => DataSource.getComments()
);

В этом случае CommentList - это компонент, который нужно обернуть, а DataSource.getComments () - это функция, которая должна выполняться для извлечения некоторых данных из DataSource. Вы видите выгоду? У вас будет возможность подписаться / отказаться от подписки на DataSource и получить из него некоторые данные без какой-либо фактической логики, подразумеваемой в компоненте, который вы хотите, просто заключив его в функцию withSubscription.

Почему переход от HOC к React Hook?

Но зачем переходить с HOC и использовать вместо него React Hook? Что ж, я не претендую на то, чтобы сказать, что HOC - это плохо, но я определенно думаю, что они являются хорошим источником Wrapper Hell в ваших проектах, особенно когда дело касается отладки и тестирования.

Это мое личное мнение. Но в любом случае, если вы не согласны со мной, ничего страшного. Я все еще думаю, что вам это будет очень интересно.

Внедрение HOC

Чтобы лучше понять, что мы делаем, я кое-что уладил:

  1. Поддельный источник данных:

2. Полная версия HOC:

3. Два компонента, использующие HOC:

Как видите, у такого подхода есть несколько больших преимуществ:

  • У нас есть общая логика внутри HOC. Нет повторяющегося кода.
  • Наши компоненты выглядят очень чистыми. Нам даже не нужно реализовывать componentDidMount или componentWillUnmount в наших компонентах BlogPost и CommentList.

Так что это здорово. Мы разделяем некоторую логику для любого компонента, который соответствует нашей реализации HOC.

Но есть кое-что, что мы можем улучшить в этой реализации: мы можем воспользоваться преимуществами React Hooks, чтобы заменить HOC, и, таким образом, мы получим от этого выгоду, отказавшись от использования оболочки для каждого из наших компонентов и исключив использование классы (что является исходной мотивацией для хуков, как указано в документации на https://reactjs.org/docs/hooks-intro.html#motivation).

Представляем наш собственный хук useSubscription

Всякий раз, когда я пытаюсь создать что-то новое, я всегда начинаю с представления решения, которое хочу иметь: как оно должно выглядеть?

И это первое, что пришло мне в голову, когда я подумал об этом:

useSubscription (myFunctionToSelectData)

И я хочу представить компонент BlogPost с простым вызовом моего настраиваемого обработчика с параметром (ds) = ›ds.getPost (id). И это должно быть так, кастомный хук должен позаботиться о:

  1. Выполнение подписки / отказа от подписки на DataSource
  2. Сохраните результат моей функции selectData, в данном случае ds.getPost (id)

Время для шоу! Давайте начнем с нашего настраиваемого хука:

Следуя правилам команды React, нам нужно назвать наш настраиваемый хук словом use в начале, поэтому я назвал его useSubscription. И единственное, что нам нужно вернуть, - это фактические данные, созданные функцией selectData. Так что это единственное, что у меня на крючке: подпись и возвращаемые данные (которые мне еще нужно определить).

Представляем ловушку React useState

Найдите время, чтобы ознакомиться с документацией по React useState. Мы будем использовать этот хук для сохранения результата нашей функции selectData:

Это довольно просто, мы используем React.useState для хранения результата нашего селектора. React.useState возвращает две вещи: текущее значение, которое мы сохраняем, и функцию для изменения этого значения. В нашем случае data хранит результат нашего селектора, и функция setData будет использоваться для его обновления, чего у нас сейчас нет, мы ' re нигде не обновляет нашу переменную состояния data.

Вы не поверите, но эта простая реализация частично сработает. Чего нам не хватает, так это способа отправки изменений в наши компоненты, потому что прямо сейчас мы разрешаем наш селектор изначально, но что, если базовые данные изменятся в будущем? Нам нужно знать об этих изменениях. Так что давай сделаем это.

Введение в React useEffect hook

Опять же, вам следует потратить немного времени на изучение документации по хуку React useEffect. Мы будем использовать ловушку React.useEffect для обработки событий подписки / отмены подписки в компонентах, полагающихся на нашу настраиваемую ловушку. Проверить реализацию:

Мы подписываемся / отказываемся от подписки на изменения в DataSource с помощью ловушки React.useEffect. Таким образом, когда компонент, использующий ловушку useSubscription, смонтирован, он будет подписан на изменения DataSource, а когда он будет отключен, он будет отписан.

Как видите, на хуке useEffect мы снова выполняем функцию selectData для извлечения в этот конкретный момент базовых данных всякий раз, когда DataSource указывает, что произошло изменение. Вот так наши компоненты будут синхронизироваться с источником данных.

Если у вас есть сомнения относительно того, как работает useEffect, проверьте документацию, чтобы понять, что на самом деле происходит.

Рефакторинг наших компонентов.

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

Что вы думаете? Найдите минутку, чтобы подумать об изменениях и последствиях. Вот преимущества, которые я вижу:

  1. Нет больше оберток. Наше дерево React будет чище, потому что мы не увидим обертку для компонентов, использующих наш собственный хук.
  2. Больше никаких занятий. Вы видите эти прекрасные функциональные компоненты? Это делает наши компоненты проще и чище.
  3. Мы по-прежнему повторно используем логику в наших компонентах.
  4. С HOC, если бы нам пришлось делиться большей логикой, нам нужно было бы добавить еще одну оболочку для наших компонентов, но с React Hooks это просто вопрос вызова этого нового хука внутри нашего компонента.

Вы используете HOC в своем проекте? Почему бы вам не попробовать создать собственную замену крючка для одного из них?

Спасибо за чтение и дайте мне знать, что вы думаете по этому поводу.