"Закрытый" компонент
ОБНОВЛЕНИЕ 2018: в учебнике хорошая теория, но ему уже два года. Проверяйте версии пакетов. За выходом нового учебника можно следить в telegram канале или twitter
На канале так же проводятся бесплатные вебинары, публикуются переводы и авторские материалы, присоединяйтесь!
"Закрытый" компонент
Для урока, я использовал этот пример.
В конце прошлого раздела у нас осталась проблема - все имеют доступ к /admin. Мы уже решали ее в первой части с помощью хука на onEnter. Но для связки redux + react-router мне нравится подход с "закрытым" компонентом.
Помните, мы делали <NavLink />
обертку? Как я уже писал - это очень мощный прием. Сейчас мы воспользуемся им [приемом] еще раз.
AuthenticatedComponent
Начнем с размышлений и псевдокода:
Закрытый_компонент.js
Что ж, выглядит "заумно"? На деле - воспользуемся старой доброй возможностью прокидывать аргументы в функцию. А так же, сразу сделаем нашу обертку "приконекченной" (connect).
src/containers/AuthenticatedComponent/index.js
В render методе мы проверяем - есть ли у user право видеть данный компонент, и если да - показываем. Если нет - null.
Обновим роуты:
src/routes.js
Опять же, почувствуйте все удобства "оборачивания": нам вообще не нужно ничего делать с компонентом <Admin />
.
Перекур. Интересный момент. На дворе 22.04.2016 и мой хром версии - 50.0.2661.75 (64-bit) + React dev tools последней версии.
Давайте проверим как работает наш подход. Зайдите на /login
, залогиньтесь и после редиректа посмотрите в инспектор:
Выглядит не так, как мы ожидали. Вероятно, должно было быть так:
Но у нас:
До текущего момента мы сделали очень много работы, чтобы все работало так как мы ожидаем, не так ли? Если мы пишем console.log - у нас возникает один console.log (камень в огород Angular), если мы хотим чтобы "роутинг" был частью потока данных - мы и это делаем в соответствии с документацией. Тогда в чем дело?
Посмотрите внимательно на код AuthenticatedComponent. У нас и аргумент функции Component и класс наследует Component. Вероятно, проблема здесь. Давайте просто импортируем чуть-чуть иначе, а название аргумента сохраним.
src/containers/AuthenticatedComponent/index.js
Ожидаемо и предсказуемо. Перекур завершен.
P.S. было "extends Component", стало "extends React.Component" (конечно, строка импорта тоже изменилась)
Редирект на страницу логина, если пользователь не аутентифицирован
Мы почти закончили. На данный момент:
после логина - редирект
при попытке неавторизованному пользователю зайти на
/admin
- пусто (вместо null можете выводить "403 - доступ запрещен", либо можете создать компонент<NoAccess />
...)
Тем не менее, по условию задачи: если пользователь неавторизован - перенаправь его на /login
.
Для этого воспользуемся lifecycle-методами (методами жизненого цикла): componentWillMount и componentWillReceiveProps
src/containers/AuthenticatedComponent/index.js
Поскольку, AuthenticatedComponent присоединен, у нас есть возможность использовать this.props.dispatch
.
Для истории браузера используется метод replace, так как нам это подходит лучше (после проверки, замените на push и походите "Назад/Вперед").
Измените на replace и в UserActions.
src/actions/UserActions.js
Проверьте в браузере.
Итого: мы рассмотрели еще один пример "оборачивания" компонента, тем самым получив необходимый для решения задачи редирект.
P.S. вы можете использовать "оборачивание", для скрытия каких-то элементов на странице, а не только всей страницы целиком.
Исходный код на данный момент.
Last updated