3.12.1 Представляем хуки


Хуки доступны в версии React 16.8. Они позволяют вам использовать состояние и другие функции React без написания класса.


Код
    
  import { useState } from 'react';

  function Example() {
    // Объявляем новую переменную состояния, которую назовём "count"
    const [count, setCount] = useState(0);
  
    return (
      <div>
        <p>Вы кликнули {count} раз</p>
        <button onClick={() => setCount(count + 1)}>
          Кликни меня!
        </button>
      </div>
    );
  }
  

Новая функция useState является «хуком» (в оригинале hook - крюк). О ней мы поговорим позднее, а данный пример - просто тизер. Не переживайте, если пока не понимаете приведенный код!

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


Внимание!

React 16.8.0 - это первый релиз, поддерживающим хуки. При апгрейде не забудьте обновить все пакеты, включая React DOM. React Native будет поддерживать хуки в следующем стабильном релизе.



3.12.1.1 Видео

На React конференции 2018 Софи Альперт и Дэн Абрамов представили хуки, а затем Райан Флоренс продемонстрировал, как выполнить рефакторинг приложения для их использования. Смотрите видео:





3.12.1.2 Критические изменения отсутствуют


Прежде чем продолжить, обратите внимание, что хуки:

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

  • 100% обратно-совместимые. Хуки не содержат каких-либо критических изменений.

  • Доступны сейчас. Хуки доступны, начиная с релиза v16.8.0.

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

Хуки не исключают ваши знания концепций React. Вместо этого, хуки предоставляют более прямой API для уже знакомых вам понятий React: свойства, состояние, контекст, ссылки ref и жизненный цикл. Как мы покажем позже, хуки также предлагают новый мощный способ их комбинирования.

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



3.12.1.3 Мотивация


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




3.12.1.3.1 Тяжело повторно использовать логику состояний между компонентами


React не предлагает способ «прикрепить» повторно используемое поведение к компоненту. Если вы какое-то время работали с React, вы можете быть знакомы с такими паттернами, как свойство render и компоненты более высокого порядка, которые пытаются решить эту проблему. Но для своего использования данные паттерны требуют, чтобы вы реструктурировали свои компоненты, что может сделать код сложным и громоздким. Если вы посмотрите на типичное приложение React в React DevTools, вы, скорее всего, увидите «адское обёртывание» компонентов, находящимися под слоями провайдеров, потребителей, компонентов более высокого порядка, свойств render и других абстракций. Хотя мы и можем отфильтровать их в DevTools, всё же это указывает на более глубокую скрытую проблему: React нужен лучший примитив для обмена логикой состояний.

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

Мы обсудим это подробнее в разделе «Создание собственных хуков».


3.12.1.3.2 Сложные компоненты становятся тяжелыми для понимания


Нам часто приходилось поддерживать компоненты, которые вначале были простыми, но переросли в неуправляемый беспорядок, состоящий из логики состояния и побочных эффектов. Каждый метод жизненного цикла часто содержит смесь несвязанной логики. Например, компоненты могут выполнять некоторую выборку данных в componentDidMount и componentDidUpdate. Однако тот же метод componentDidMount может также содержать некоторую логику, которая устанавливает слушатели событий, а очистка выполняется в componentWillUnmount. Таким образом совершенно не связанный код в конечном итоге объединяется в одом методе. В таком коде очень легко вводить ошибки и несоответствия.

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

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

Мы обсудим это подробнее в разделе «Создание хука эффекта».


3.12.1.3.3 Классы путают как людей, так и машины


В добавок к усложнению повторного использования и организации кода мы обнаружили, что классы могут стать серьезным препятствием для изучения React. Вы должны понимать, как в JavaScript работает this, что сильно отличается от того, как он работает в большинстве языков. Вы должны не забыть привязать обработчики событий. Без нестабильного синтаксического сахара код очень громоздкий. Люди могут отлично понимать свойства, состояние и нисходящий поток данных, но все еще сражаться с классами. Различие между компонентами-функциями и классами в React и тем, когда их использовать, приводит к разногласиям даже между опытными разработчиками React.

Кроме того, React существует уже около пяти лет, и мы хотим убедиться, что он останется актуальным и в течение последующих пяти лет. Как показывают Svelte, Angular, Glimmer и другие, предварительная компиляция компонентов имеет большой потенциал в будущем. Особенно если это не ограничено шаблонами. Недавно мы экспериментировали со складыванием (фолдингом - folding) компонентов с помощью Prepack и получили многообещающие первые результаты. Однако мы обнаружили, что компоненты-классы могут стимулировать непреднамеренные шаблоны, которые вынуждают эти оптимизации идти по более медленному пути. Классы также представляют проблемы для современных инструментов. Например, классы не очень хорошо минимизируются, также они делают горячая перезагрузку ненадежной. Мы хотим представить API, который повысит вероятность того, что код останется на оптимизируемом пути.

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


Примеры

Краткий обзор хуков - это хорошее место для начала изучения.



3.12.1.4 Стратегия постепенного внедрения



Внимание!

Нет планов по удалению классов из React.

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

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

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

Наконец, нет никакой весомой необходимости переходить на хуки. Мы рекомендуем избегать любых «больших переделок», особенно для существующих сложных компонентов-классов. Чтобы начать «думать в терминах хуков» необходим некоторый "умственный сдвиг". По нашему опыту, лучше всего потренироваться в использовании хуков сначала на новых и некритических компонентах, убедившись, что все члены вашей команды чувствуют себя с ними комфортно. После того, как вы попробуете хуки, отправьте нам свой отзыв, неважно, положительный или отрицательный.

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



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


Раздел FAQ по хукам отвечает на наиболее распространенные вопросы.



3.12.1.6 Следующие шаги


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