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

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

Что такое крючки?

«Хуки - это новое дополнение к React в версии 16.8, которое позволяет вам использовать состояние и другие функции React, такие как методы жизненного цикла, без написания класса».

Дэн Абрамов подробно рассказал об API, а также о том, как и почему фреймворк, который многие из нас используют, превратился в то, что есть сейчас. Вы можете прочитать об этом и посмотреть его программный доклад на ReactConf 2018, в котором представлено предложение хуков здесь.

Ключевой вывод может заключаться в следующем:

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

Классы в JavaScript поощряют множественные уровни наследования, которые быстро увеличивают общую сложность и вероятность ошибок; все, что позволяет композицию с простыми функциями, является победой. В OddBird мы были рады оставить компоненты класса позади в нашем последнем новом проекте и получили большую выгоду от наличия простых, последовательных шаблонов для управления состоянием и совместного использования логики с отслеживанием состояния между компонентами за счет использования нового API хуков.

Управление состоянием приложения

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

С хуками этот компонент, который поддерживает свои собственные данные внутреннего состояния

… Можно упростить до половины строк кода, достигнув тех же результатов.

В первом примере мы видим, что есть три отдельных метода (componentDidUpdate, componentDidMount и tick) для выполнения одной и той же задачи: синхронизировать счетчик, отображаемый в пользовательском интерфейсе, на основе значения секунд.

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

Совместное использование состояния с контекстом

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

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

Создайте объект контекста:

const CountContext = React.createContext({})

useContext

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

Используйте объект Context во вложенном компоненте.

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

Использование хуков с Redux

Мы используем Redux для управления состоянием, потому что шаблоны действий / редукторов помогают сохранить детерминированность и организованность состояния. React Redux предоставляет официальные привязки React для Redux и теперь предлагает хуки в качестве альтернативы использованию Connect Higher Order Component (HOC) для подписки и внесения изменений в данные в вашем хранилище Redux.

В этом есть свои преимущества, но хуки response-redux становятся немного сложнее с запоминанием селекторов и избеганием ненужных повторных рендеров; мы можем или не можем использовать useMemo и useCallback правильно во всех нужных местах.

useReducer

Несмотря на то, что он указан в документации React в разделе Additional Hooks, важно отметить, что useReducer является альтернативой useState и рекомендуемым способом управления состоянием компонента, когда данные вашего приложения более сложные, содержат объекты с несколькими вложенными значениями или когда следующее состояние зависит от предыдущего.

Он принимает редуктор типа (состояние, действие) = ›newState и возвращает текущее состояние вместе с методом отправки. Звучит знакомо? Этот шаблон мощный и потенциально может иметь несколько вариантов использования.

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

Совместное использование невизуальной логики

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

Здесь мы берем логику с отслеживанием состояния из нашего компонента Timer, чтобы создать нашу собственную настраиваемую ловушку.

Пользовательские хуки представляют собой композицию основных хуков, таких как useState и useEffect, инкапсулированных в функцию JavaScript, имя которой начинается с «use».

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

В заключение…

Использование Hooks as принесло нам следующие преимущества:

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

Если наших мотиваторов недостаточно, чтобы вы попробовали, в официальной документации есть несколько достойных аргументов, которые стоит учесть. В настоящее время мы не уверены, какое место занимает Redux с нашим использованием хуков. Мы, конечно, могли обойтись без Redux, используя useReducer, но это еще не все.

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

Привет! Я Эрика Митчелл (она же Дагги) и я старший разработчик фронтенда в Oddbird, небольшом агентстве разработчиков и дизайнеров, которое помогает клиентам создавать масштабируемые и высокопроизводительные веб-приложения с ориентированным на человека дизайном.

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

Учить больше