Что такое Redux: руководство дизайнера

Опубликовано: 2022-03-10
Краткое резюме ↬ Знаете ли вы, что реальная сила Redux не ограничивается управлением состоянием? Вы хотите проектировать с пониманием того, как работает Redux? Давайте углубимся в то, что может сделать Redux, почему он делает то, что нужно, каковы его недостатки и как он связан с дизайном.

Вы слышали о Редукс? Что это такое? Не гуглите, пожалуйста!

  • «Необычные бэкэнд-штучки».
  • — Я слышал об этом, но не знаю, что это такое. Возможно, это фреймворк React?»
  • «Лучший способ хранить состояния и управлять ими в приложении React».

Я задал этот вопрос более чем 40 дизайнерам. Выше приведены их типичные ответы. Многие из них знают, что Redux работает с React и его задача — «управление состоянием».

Но знаете ли вы, что на самом деле означает это «управление государством»? Знаете ли вы, что реальная сила Redux не ограничивается управлением состоянием? Знаете ли вы, что для работы Redux не обязательно требуется React ? Вы хотите присоединиться к обсуждению вашей команды (или, по крайней мере, к обеденным чатам) о том, стоит ли использовать Redux? Вы хотите проектировать с пониманием того, как работает Redux?

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

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

Готовы к поездке?

Еще после прыжка! Продолжить чтение ниже ↓

Что такое Редукс?

На сверхвысоком уровне Redux — это инструмент, который разработчики используют для облегчения своей жизни. Как многие из вас, возможно, слышали, его работа — «управление состоянием». Я объясню, что означает управление состоянием, несколькими разделами позже. На этом этапе я оставлю вас с этой картинкой:

Redux менеджер состояний.
Redux управляет состоянием, но в фоновом режиме есть несколько скрытых возможностей. (Иллюстрация Биби) (Большой превью)

Почему вы должны заботиться?

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

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

«Дизайн — это не только то, как он выглядит и на что он похож. Дизайн — это то, как это работает».

- Стив Джобс

Что может Редукс?

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

Однако вскоре вы увидите, что реальная мощь Redux выходит далеко за рамки этого. Давайте начнем с изучения того, что на самом деле означает управление состоянием.

Государственное управление

Если вы не уверены, что означает это «состояние», давайте заменим его более общим термином: «данные». Состояние — это данные, которые время от времени изменяются . Состояние определяет, что отображается в пользовательском интерфейсе.

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

  1. Получение и сохранение данных
  2. Назначение данных элементам пользовательского интерфейса
  3. Изменение данных

Допустим, мы создаем страницу снимков Dribbble. Какие данные мы хотим отобразить на странице? Они включают фото профиля автора, имя, анимированный GIF, количество сердечек, комментарии и так далее.

Данные на странице снимков Dribbble
Данные на странице выстрела Dribbble (большой предварительный просмотр)

Во-первых, нам нужно получить все эти данные с сервера в облаке и поместить их куда-нибудь. Далее нам нужно фактически отобразить данные. Нам нужно назначить части этих данных соответствующим элементам пользовательского интерфейса, которые представляют то, что мы на самом деле видим в браузере. Например, мы назначаем URL-адрес фотографии профиля атрибуту src HTML-тега img :

 <img src='https://url/to/profile_photo'>

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

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

Извлечение и хранение данных

В React мы разбиваем пользовательский интерфейс на компоненты. Каждый из этих компонентов можно разбить на более мелкие компоненты (см. «Что такое React?»).

Страница Dribbble Shot разбита на компоненты
Страница снимков Dribbble разбита на компоненты (большой предварительный просмотр)

Если наш пользовательский интерфейс структурирован таким образом, когда мы извлекаем данные и где их хранить перед заполнением пользовательского интерфейса?

Представьте, что в каждом компоненте живет шеф-повар . Получение данных с серверов похоже на поиск всех ингредиентов, необходимых для приготовления блюд.

Наивный способ — извлекать и хранить данные там, где и когда они нужны. Это похоже на то, как если бы каждый повар ходил покупать овощи и мясо прямо с дальних ферм.

Наивный способ: извлекать данные из каждого компонента.
Наивный способ: извлекать данные из каждого компонента. (Иллюстрация Биби) (Большой превью)

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

С Redux мы извлекаем данные один раз и сохраняем их в центральном месте, удобно называемом «хранилище». Затем данные готовы к использованию любым компонентом в любое время. Это похоже на то, что поблизости есть супермаркет, где наши повара могут купить все ингредиенты. Супермаркет отправляет грузовики, чтобы доставить овощи и мясо оптом с ферм. Это намного эффективнее, чем просить отдельных поваров отправиться на ферму самостоятельно!

Магазин также служит единственным источником правды. Компоненты всегда извлекают данные из хранилища, а не откуда-либо еще. Это обеспечивает единообразие всего содержимого пользовательского интерфейса.

Redux как центральное хранилище данных.
Redux как центральное хранилище данных. (Иллюстрация Биби) (Большой превью)

Назначение данных элементам пользовательского интерфейса

Только с React на самом деле есть лучший способ извлечения и хранения данных. Мы можем попросить нашего очень доброго шеф-повара Шотвелла сделать покупки для всех его друзей-поваров. Он водил грузовик на фермы и отвозил товары. Мы могли бы получить данные из компонента-контейнера, например, компонента «Выстрел» в примере с Dribbble, и использовать его как единственный источник правды.

Получить данные из корневого компонента.
Получить данные из корневого компонента. (Иллюстрация Биби) (Большой превью)

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

Например, URL-адрес аватара автора нужно передать из «Shot», «ShotDetail», «Title» и, наконец, в <img> . Если наши повара живут в квартире, то это действительно выглядит так:

Передайте данные компонентам через реквизиты.
Передайте данные компонентам через реквизиты. (Иллюстрация Биби) (Большой превью)

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

Что, если супермаркет осуществляет доставку «от двери до двери»? С Redux 1 мы можем подключать любые данные к любому компоненту, вообще не затрагивая другие компоненты, например:

1 Чтобы быть абсолютно точным, это другая библиотека под названием react-redux , которая передает данные компонентам React, а не сама Redux. Но поскольку react-redux всего лишь выполняет сантехнику, а люди почти всегда используют Redux и react-redux вместе, я думаю, что можно включить это как одно из преимуществ Redux.

Подключайте данные к компонентам с помощью Redux.
Подключайте данные к компонентам с помощью Redux. (Иллюстрация Биби) (Большой превью)

Примечание . В последней версии React (16.3) появился новый «контекстный» API, который выполняет почти ту же работу с точки зрения подключения данных к компонентам. Так что, если это единственная причина, по которой ваша команда использует Redux, серьезно подумайте об обновлении до React 16.3! Ознакомьтесь с официальным документом для получения дополнительной информации (предупреждение: впереди много кода).

Изменение данных

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

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

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

Разделите сложную логику на редюсеры.
Разделите сложную логику на редюсеры. (Иллюстрация Биби) (Большой превью)

Тем не менее, следите за последним развитием React. Как и в случае с «контекстным» API, в будущей версии React может появиться новый API «setState». Было бы проще разбить сложную логику обновления на более мелкие части. Как только этот новый API станет доступным, возможно, вам больше не понадобится Redux для управления этим аспектом управления состоянием.

Настоящая сила Redux

Пока кажется, что Redux — это просто пластырь для React. Люди используют Redux для улучшения аспектов, с которыми React не справляется (пока). Но React быстро догоняет! Фактически, Дэн Абрамов, создатель Redux, присоединился к основной команде React в Facebook пару лет назад. Они были заняты работой над вышеупомянутыми улучшениями React: контекстный API (выпущен в версии 16.3), улучшенный API для выборки данных (демонстрация в феврале 2018 г.), улучшенный API setState и так далее.

Сделает ли это Redux устаревшим?

Угадай, что? Я еще не показал вам настоящую мощь Redux!

Сила Redux выходит далеко за рамки управления состоянием.
Сила Redux выходит далеко за рамки управления состоянием. (Иллюстрация Биби) (Большой превью)

Redux заставляет разработчиков следовать нескольким строгим правилам, которые дают Redux большую силу (ага, силу дисциплины!):

  1. Все данные (состояние приложения) должны быть описаны открытым текстом. Вы должны быть в состоянии записать все данные ручкой на бумаге.
  2. Каждое действие (изменение данных) должно быть описано открытым текстом. Вы должны записать, что вы будете делать, прежде чем что-либо менять. Вы не можете изменить данные, не оставив отметки. Этот процесс называется «отправка действия» на сленге Redux.
  3. Ваш код, изменяющий данные, должен вести себя как математическая формула. Он должен возвращать тот же результат при тех же входных данных. Квадрат 4 всегда равен 16, сколько бы раз вы его ни запускали.

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

2 Я собрал эти примеры из поста Дэна Абрамова «Вам может не понадобиться Redux» и его «Вопросы для новичков в React».

Отменить повторить

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

Отменить повторить.
Отменить повторить. (Иллюстрация Биби) (Большой превью)

Поскольку Redux требует, чтобы каждое действие было описано открытым текстом, поддержка отмены/возврата почти бесплатна. Инструкции по реализации отмены/возврата с помощью Redux умещаются на простой странице.

Совместная среда

Если вы создаете приложение, похожее на Google Docs, в котором несколько пользователей совместно работают над сложной задачей, рассмотрите возможность использования Redux. Это, вероятно, сделает много тяжелой атлетики для вас.

Гугл документы
Документы Google (иллюстрация Beebee) (большой предварительный просмотр)

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

Оптимистичный интерфейс

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

оптимистичный пользовательский интерфейс
Оптимистичный пользовательский интерфейс (иллюстрация Beebee) (большой предварительный просмотр)

В качестве простого примера, в приложении Twitter, когда вы нажимаете сердечко в твите, ему необходимо запросить у сервера несколько проверок, например, существует ли еще этот твит. Вместо того, чтобы ждать много секунд результата, приложение выбирает обман! Он предполагает, что все в порядке, и сразу показывает наполненное сердце.

Твиттер сердце
Сердце Twitter (иллюстрация Beebee) (большой превью)

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

Redux поддерживает оптимистичный пользовательский интерфейс так же, как и для отмены и повтора. Это позволяет легко записывать, воспроизводить и отменять изменения данных при получении отрицательного результата от сервера.

Сохранение и загрузка из состояния

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

Сохранить/загрузить игровой прогресс
Сохранение/загрузка прогресса игры (Иллюстрация Beebee) (Большой превью)

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

Действительно расширяемые системы

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

Вы можете создавать действительно расширяемые приложения, в которых каждая функция может быть настроена пользователем. Например, проверьте Hyper, терминальное приложение, созданное с помощью Redux. Расширение «гипермощь» добавляет брызги к курсору и встряхивает окно. Как вам такой «вау»-режим? (Возможно, не очень полезно, но достаточно, чтобы произвести впечатление на пользователей)

Режим «вау» в Hyper, терминальном приложении.
Режим «вау» в Hyper, терминальном приложении. (Большой превью)

Отладка путешествия во времени

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

Redux воплощает в жизнь эту мечту разработчиков. Redux DevTools позволяет вам управлять ходом работы запущенного приложения как видео на YouTube — перетаскивая ползунок!

Как это работает? Помните три строгих правила, которых придерживается Redux? Это секретный соус магии.

Путешествие во времени в Redux DevTools
Путешествие во времени в Redux DevTools Большой превью

Автоматические отчеты об ошибках

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

Теперь, как насчет этого. Пользователь нажимает кнопку «Сообщить об ошибке». Система автоматически отправляет то, что она сделала, разработчику. Разработчик нажимает кнопку «Повторить ошибку» и смотрит, как именно происходит эта ошибка. Баг ликвидирован на месте, все довольны!

Это именно то, что произойдет, если вы используете Redux Bug Reporter. Как это работает? Ограничения Redux творят чудеса.

Автоматические отчеты об ошибках
Автоматизированные отчеты об ошибках (иллюстрация Beebee) (большой предварительный просмотр)

Недостатки Redux

Три основных правила, которых придерживается Redux, — палка о двух концах. Они обеспечивают мощные функции, но в то же время вызывают неизбежные недостатки.

Крутая кривая обучения

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

«Шаблонный» код

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

Я знаю, это звучит противоречиво. Разве я не говорил, что Redux позволяет реализовать функции с минимальным кодом ? Это немного похоже на использование посудомоечной машины. Во-первых, вам придется потратить время на то, чтобы аккуратно расставить посуду в ряды. Только тогда вы увидите преимущества посудомоечной машины: экономия времени на мытье посуды, дезинфекция посуды и т. д. Вы должны решить, стоит ли время подготовки!

Штраф за производительность

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

Бонус: Redux не только для React

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

Однако на самом деле Redux может работать с любыми интерфейсными фреймворками, такими как Angular, Ember.js или даже jQuery, или даже ванильный JavaScript. Погуглите, найдете это, это, это или даже это. Общие идеи Redux применимы везде!

Если вы используете Redux с умом, вы можете получить его преимущества во многих ситуациях — не только в приложении React.

Redux хорошо работает с другими интерфейсными библиотеками.
Redux хорошо работает с другими интерфейсными библиотеками. (Иллюстрация Биби) (Большой превью)

Заключение

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

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

Поймите преимущества и ограничения технологии и проектируйте соответственно. Я думаю, именно это имел в виду Стив Джобс, говоря: «Дизайн — это то, как это работает».