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

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

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

Пример

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

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

Набросок компонентов

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

Вот основные компоненты, которые я вижу:

  • Страница пользователя
  • Список пользователей
  • Пользовательский элемент

Вы можете спросить: «А как насчет поля поиска, кнопки и обратной ссылки?» Они не менее важны, но я считаю эти компоненты многократного использования. Очень важно отсканировать дизайн, потому что мы хотим сделать их достаточно абстрактными, чтобы мы могли использовать их и в других местах. Мы могли бы сначала начать создавать их, прежде чем мы сможем составить эту страницу.

Обязанности

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

Страница пользователя

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

Список пользователей

Этот компонент отвечает за отображение списка пользователей.

Пользовательский элемент

Этот компонент отображает сведения о пользователе и обрабатывает действия редактирования и удаления.

Поток данных

Прежде чем мы начнем программировать этот пользовательский интерфейс, давайте также сначала подумаем о потоке данных на этой странице. Ниже представлена ​​визуализация того, как я предлагаю данные проходить через приложение:

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

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

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

А как насчет действий пользователя?

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

  • Дескриптор в самом пользовательском элементе.
  • Передайте функцию со страницы пользователя, которая будет вызываться.

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

Другая причина связана с ответственностью: разве пользовательский элемент не должен отвечать за редактирование и удаление пользовательской записи? Если вас беспокоит опасность раздуть компонент бизнес-логикой, эту проблему можно решить, переместив логику на уровень ловушки или сервиса.

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

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

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

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

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

Заключение

Надеюсь, эта статья дала вам некоторое представление о том, как я подхожу к определению компонентов и состояния в приложении.

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

Ресурсы