Перейти к содержанию

Введение в хуки

Хуки — нововведение в React 16.8, которое позволяет использовать состояние и другие возможности React без написания классов.

import React, { useState } from 'react'

function Example() {
  // Объявление переменной состояния, которую мы назовём "count"
  const [count, setCount] = useState(0)

  return (
    <div>
      <p>Вы кликнули {count} раз</p>
      <button onClick={() => setCount(count + 1)}>Нажми на меня</button>
    </div>
  )
}

Первый хук, который мы изучим, это функция useState. Не беспокойтесь, если этот пример будет поначалу неясен. Скоро мы разберёмся, как он работает.

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

Примечание

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

Полная обратная совместимость

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

  • Полностью на ваше усмотрение. Вы можете попробовать хуки в одних компонентах, не изменяя код в других. Хуки не обязательно использовать или изучать прямо сейчас.
  • 100% обратно совместимы. Хуки не содержат изменений, которые могут поломать ваш существующий код.
  • Доступны прямо сейчас. Хуки доступны с выходом версии 16.8.0.

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

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

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

Мотивация

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Примеры

Обзор хуков — хорошее начало для изучения хуков.

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

TLDR: Мы не планируем удалять классы из React.

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

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

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

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

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

Мы подготовили для вас страницу FAQ с ответами на самые частые вопросы о хуках.

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

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