Frontend разработчик в компании Usetech Перевод данной статьи был выполнен с оригинального источника, автор — Tanveer Singh. Управление состоянием является одной из самых больших проблем при использовании фреймворка React. Это касается не только пользователей. Разработчикам нужен простой и масштабируемый процесс управления состоянием для проектирования эффективных и сложных пользовательских интерфейсов. Обычно используют хуки React для доступа и обмена состояниями между разными компонентами. Но при работе с их значительным количеством сложность становится слишком большой для хуков. В таких случаях необходимо использовать библиотеки управления состоянием. Как выбрать библиотеку, которая лучше всего подходит именно вам? Это зависит от нескольких факторов. Давайте узнаем больше о наиболее важных библиотеках и о том, на что обращать внимание при принятии решения. Состояние представляет собой часть компонента, которая изменяется в зависимости от действий пользователя. Это объект JavaScript, который служит памятью компонента и хранит многие его свойства. Таким образом, управление состоянием в React — это процесс обмена данными между различными компонентами. Когда пользователь взаимодействует с вашим React приложением, в состоянии одного или нескольких компонентов могут происходить изменения. Эти изменения могут повлиять на интерфейс (UI), представленный пользователю, поэтому вам необходимо управлять ими. Управление состоянием чрезвычайно важно для сохранения целостности приложения, так как оно обеспечивает простоту взаимодействия с пользователем. Когда пользователи взаимодействуют с вашим React приложением, каждое их действие может изменить состояние нескольких компонентов. Возьмем, к примеру, приложение интернет-магазина, в котором покупка товара может повлиять на несколько компонентов посредством следующих действий: Добавление товаров в корзину Добавление товаров в историю заказов покупателя Изменение количества купленных товаров В таком сценарии со сложными элементами, взаимодействующими друг с другом и требующими обмена состояниями между собой, легко нарушается масштабируемость. Если не внедрены надёжные библиотеки управления состоянием, задача частой отладки и исправления приложения может быстро стать нереализуемой. Управление состоянием имеет важное значение для обеспечения простой, согласованной и масштабируемой передачи состояний между несколькими компонентами. Библиотеки управления состоянием предлагают новые подходы, делая это эффективно и помогая разработчикам создавать масштабируемые и интерактивные приложения на React. Эти библиотеки представляют собой модульные фрагменты кода, которые учитывают передовые методы управления состоянием. Освоить их легко и просто. И у разработчиков есть широкий выбор как из проверенных, так и из новых. Различные библиотеки используют разные подходы для достижения одного и того же результата. Они также отличаются друг от друга размером, поддержкой языков, документацией, поддержкой API и многим другим. Выбор будет зависеть от вашей конкретной задачи, размера проекта и квалификации команды разработчиков. На GitHub есть более 90 библиотек управления состоянием для React. Но по ряду ключевых характеристик некоторые из них выделяются среди остальных. При выборе правильной библиотеки для вашего приложения на React вы должны учитывать следующие факторы: Удобство использования Производительность Масштабируемость Модифицируемость Сложность поддержки Возможность переиспользования Тестируемость Экосистема Сообщество Мы изучили практически все доступные библиотеки управления состоянием, вам этого уже делать не нужно, и сократили их список до семи. Redux существует с 2015 года и является первой библиотекой управления состоянием в React, созданной для упрощения этого процесса путем централизации хранилища состояний, которая достигается с помощью использования «Store», содержащего все состояния вашего приложения. По результатам npmtrends на январь 2022 года, Redux по-прежнему занимает лидирующую позицию среди остальных подобных библиотек. В Redux используются экшены (actions) и редьюсеры (reducers). Экшены — это объекты, сообщающие хранилищу (store) о том, какие события должны произойти. Редьюсеры — функции, которые выполняются на основе входных данных экшена и начального состояния (initial state). Всякий раз, когда необходимо изменить состояние компонента, зависящее от поведения пользователя, вы можете отправлять (dispatch) экшен редьюсеру, который изменяет состояние и сохраняет его в хранилище. Хотя Redux широко популярен, разработчики не очень любят работать с шаблонным кодом, который тесно с ним связан. Множество экшенов и редьюсеров приводят к большому количеству кода, который становится трудно поддерживать, когда приложения становятся сложными. Для уменьшения шаблонных строк и общего упрощения можно использовать Redux Toolkit. Благодаря тому, что Redux Toolkit заботится об удобстве использования Redux, простая логика и чистые функции делают его довольно удобным в сопровождении, производительным и тестируемым. Вы можете изменять и повторно использовать код Redux, так как он не зависит от фреймворка и поддерживает промежуточный слой (middleware). И благодаря своей зрелости он имеет поддержку большого сообщества разработчиков и богатую экосистему дополнений и инструментов. Hookstate — это современная альтернатива хукам React и таким библиотекам, как Redux. Эта библиотека быстро завоевала репутацию за её минималистичность, производительность и масштабируемость. Она основана на нативных React-хуках и практически не имеет шаблонного кода, а также экшенов или редьюсеров. Эта библиотека написана на TypeScript и масштабируется для всех видов сложных React-приложений. Она также поддерживает плагины, которые можно использовать для улучшения функциональности и удобства разработчиков. Hookstate уникальна тем, что отслеживает отрисованные и обновлённые состояния. Использует такие понятия, как локальное и глобальное состояние, которые очень похожи на собственное управление состоянием в React. Но также представляет другие концепции, такие как вложенное состояние, состояние области видимости и асинхронное состояние. Эти возможности позволяют разработчикам получить доступ к сложным состояниям, отрисовывать большие состояния и использовать «обещания» (promises), чтобы задержать некоторые действия. Она блестяще проходит по таким параметрам, как удобство использования, масштабируемость и производительность. Но, будучи новой библиотекой, ей ещё предстоит пройти долгий путь с точки зрения развития экосистемы и сообщества. Еще один новый участник сцены — Recoil, выпущенный в начале 2020 года. Известен тем, что был разработан Facebook и использует подход управления состоянием похожий на React.  В настоящее время это экспериментальная библиотека, она относительно стабильна и обладает мощным функционалом. Основными концепциями, используемыми в Recoil, являются атомы (atoms) и селекторы (selectors). Атом — это единица с общим состоянием, которая представляет собой свойство единого состояния. Компонент может подписаться на атом, чтобы получить его значение. Атомы аналогичны локальному состоянию React, но с дополнительным преимуществом — они доступны между различными компонентами.  Селекторы — это чистые функции, которые получают свое значение из атомов или других селекторов. Их значение пересчитывается каждый раз, когда атомы или селекторы, на которые они подписаны, изменяют свои значения. Таким образом, Recoil отслеживает, какие компоненты используют какие атомы/селекторы, чтобы перерисовывать компонент только в том случае, если связанный атом/селектор изменит свое значение. Эта техника делает Recoil невероятно производительным и масштабируемым. Несмотря на все свои преимущества, Recoil очень новый и не имеет значительного сообщества и экосистемы. Он также зависит от React и не может быть использован с другими фреймворками. Но он интегрирован с React Suspense и исключительно хорошо зарекомендовал себя с точки зрения модифицируемости и удобства сопровождения. Jotai был анонсирован в 2021 году и реализует атомарное управление состоянием. Он обладает многими преимуществами подобных библиотек, такими как производительность, простота, а также интеграция с React Suspense и другими библиотеками из этого списка. К его выдающимся особенностям относят меньший размер, чистый API, поддержку TypeScript и большую зрелость. Благодаря своей утилизации памяти Jotai чрезвычайно производителен, не требует ключей и зависит от JavaScript для отслеживания своих атомов. Это приводит к автоматической утилизации памяти и оптимизированному её использованию. Jotai делает ещё один шаг вперед в управлении атомарным состоянием, обрабатывая практически всё как атом. Если вам чем-то не подошли ранее описанные библиотеки, то Rematch может убедить вас своим лёгким, быстрым и простым в использовании функционалом. Он упрощает настройку, уменьшает количество шаблонного кода и лучше обрабатывает побочные эффекты. Ему удаётся вместить всё это в пакет размером 1,7 КБ. Rematch, по своей сути, работает с моделями. Модели объединяют состояние, редьюсеры и эффекты в единое целое, используя лучшие практики Redux и упрощая управление состоянием. И это ещё не всё. Rematch написан на TypeScript, поддерживает широкий набор плагинов и не зависит от фреймворка. Вы можете использовать его в работе с Vue, Angular и другими. Все эти возможности делают Rematch очень удобным, производительным и масштабируемым. Rematch намного проще в освоении, чем многие другие библиотеки, обеспечивает гораздо более приятный интерфейс и, к тому же, намного легче. Для большинства проектов React разработчикам следует ознакомиться с Rematch, особенно тем, кто начинает проект с нуля. Написанная людьми из Jotai и весом менее 1 КБ, Zustand может быть самой маленькой библиотекой в этом списке. Но придраться точно не к чему. Zustand предлагает простой и минималистический API, который делает его быстрым и масштабируемым. API Zustand основан на хуках, и компоненты React могут использовать их для получения и обмена состоянием. Он легко решает распространенные проблемы в React, такие как дочерние зомби-компоненты, параллельный режим и потеря контекста между смешанными рендерами. Есть утверждение, что он является единственным менеджером управления состояния, который справился с этим. Кроме того, он рендерит компоненты только в случае изменения их состояния. Эта особенность обеспечивает чистый и легко поддерживаемый код, который короче и читабельнее, чем многие другие библиотеки из этого списка. Zustand также может управлять обновлениями временного состояния без повторного рендеринга компонентов. Этой библиотеке удалось получить более 23k звёзд на Github, что больше, чем у Rematch, Jotai и MobX. Если не считать Redux и встроенный в React контекст, MobX, вероятно, является самым популярным менеджером состояний. Он использует совершенно другой подход к управлению состоянием, чем Redux. Он следует парадигме ООП и использует паттерн наблюдателя/наблюдаемого. MobX создает наблюдаемую модель данных, на которую могут ссылаться ваши наблюдатели или компоненты. Затем он отслеживает данные, к которым обращается каждый компонент, и отображает их всякий раз, когда они изменяются. Еще одной особенностью MobX является иммутабельность (неизменяемость). Это позволяет вам автоматически обновлять состояние, избегая побочных эффектов. Поскольку он не использует экшены или редьюсеры, любые изменения состояния мгновенно отражаются в компонентах. Это делает MobX действительно реактивным. Но это также означает более короткий и менее явный код, что может быть недостатком для некоторых разработчиков, поскольку лишает их некоторой наглядности и контроля. Удобство использования, производительность и масштабируемость не вызывают проблем для MobX. Он также отличается модифицируемостью и возможностью переиспользования. И как зрелая библиотека (почти 26к звезд на GitHub), MobX не имеет недостатков в сообществе поддержки или развивающейся экосистеме. Каждый проект индивидуален и имеет свои собственные уникальные зависимости, бизнес-кейс и использование одного решения вместо другого. Все рассмотренные выше альтернативы пытаются решить одну и ту же проблему с разными подходами. Redux и MobX — это старые любимцы в сообществе и естественный выбор для большинства проектов. Знание Redux, в общем, даёт вам дополнительные преимущества при управлении состоянием в ваших проектах.  Но в некоторых случаях другие варианты могут быть более подходящими. Например, Jotai и Hookstate предлагают инновационные подходы к управлению состоянием и смогли привлечь внимание сообщества за короткий период времени.  Независимо от выбранной библиотеки, вы также должны оценить компетентность вашей команды разработчиков и их удобство работы с React в целом. Управление состоянием является постоянной проблемой для любого проекта на React. Эффективное решение этой задачи зависит не только от правильного выбора инструмента управления состоянием, но и от наличия подходящих сотрудников в вашей команде.