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

Реквизит, реквизит, реквизит

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

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

И мы можем использовать это в нашем коде:

Простой и понятный, но негибкий.

  • Каждый раз, когда мы добавляем новый вид информации об авторизации для пользователя, мы должны добавлять новые реквизиты для соответствия.
  • Семантика не ясна. В последнем примере мы ожидали, что пользователь будет соответствовать обоим условиям, но наша проверка проходит, когда выполняется одно условие. Чтобы исправить это, нам нужно добавить дополнительные логические компоненты prop requireAll или nest Visible. Мех.

Используйте функции, чтобы иметь гибкий компонент

Чтобы сделать Visible гибким, нам нужно использовать самый полезный инструмент, доступный в JavaScript: скромную функцию.

Мы можем изменить компонент, чтобы использовать опору when, которая получает функцию (user) => boolean, определяющую политику авторизации:

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

Дополнительные преимущества

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

В версии на основе props нам приходится иметь дело с двумя ветвями кода, одна для работы с правами собственности, а другая - с ролью:

Функции справляются с этим, не беспокоясь:

Отлично.

Делаем API более дружелюбным

Нет сомнений в гибкости, достигаемой за счет использования функций, но мы не можем отрицать, что версия props намного более компактна и удобочитаема: roles={["admin"]} vs when={(user) => user.roles.includes(“admin”)}.

Итак, возможно ли найти золотую середину между гибкостью и удобочитаемостью? Да, это так. Просто используйте больше функций.

Расширение пользователя

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

Это лучше, но все же немного многословно. И нам также нужно изменить userWrapper, чтобы иметь дело с новыми характеристиками авторизации.

Использование только функций

Как и предсказывалось в названии этой истории, лучшее решение - использовать только функции.

Мы предоставляем функцию для каждого условия и способ их составить. Введитеlogin, inRole, any и all.

Отлично.

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

Подводя итоги

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

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