Взаимодействуем с VK

Чтобы работать с VK API вам необходимо будет создать приложение на сайте vk.com, и указать в настройках URL сервера, с которого вы будете выполнять запросы.

По адресу https://vk.com/apps?act=manage создайте новое приложение (веб-сайт) и заполните поля как на скриншоте, если используете локалхост и порт 3000.

vk-app-create

Интеграция VK API

Необходимо добавить скрипт openapi (документация), а так же вызвать VK.init

Номер приложения можно посмотреть здесь:

app-number

Авторизация

Создадим действия для User.

src/actions/UserActions.js

Так как загрузка информации из профиля - действие асинхронное, мы использовали проверенную схему из трех действий:

  • XXX_REQUEST - диспатчим непосредственно перед стартом реального запроса (для юзера это выглядит, как будто во время запроса)

  • XXX_SUCCESS + данные - если все прошло успешно добавляем данные [1]

  • ХХХ_FAIL + ошибка - если что-то пошло не так

[1] Чтобы достать имя пользователя, мы вытащили его из response(r).session. Данные нам предоставил VK, так как мы подтвердили "разрешаю доступ" во всплывающем окне.

vk-app-console-log-response

"Приконнектим" в <App /> UserActions, и добавим новые свойства в компонент <User />

src/containers/App.js

Здесь мы поступили так же, как когда-то для page:

  • подписались на кусочек стора (user)

  • добавили экшен и передали его в dispatch в функции handleLoginAction

  • кусочек стора (user) и handleLoginAction - стали доступны нам в this.props

  • в <User /> передали необходимые свойства

Обновим reducer user:

src/reducers/user.js

В редьюсере есть интересные моменты:

  • когда мы начали делать запрос (LOGIN_REQUEST) мы очищаем error. Например, была ошибка, мы стали делать новый запрос - ошибка очистилась;

  • если случился LOGIN_SUCCESS - мы в name записываем action.payload (а как вы помните, там мы передаем в строке имя пользователя) и ставим статус загрузки - false (то есть, не загружается, ибо загрузилось);

  • если случился LOGIN_FAIL - опять же, загружаю? Нет, значит isFetching - false. Ошибка? Да - запиши в поле error.

Прокачаем <User />:

src/components/User.js

В коде компонента <User /> ничего необычного нет. Рендерим шаблончик (в зависимости от props).

Сейчас если кликнуть на "войти" - всплывет VK окно с подтверждением прав доступа (первый раз). После подтверждения прав, вместо кнопки войти появляется надпись "Привет, ХХХ". При перезагрузке сайта и повторных нажатиях на "войти" - VK окно мгновенно закрывается, а кнопка вновь изменяется на "Привет, XXX".

Как всегда, доблестный логгер пишет в консоли - что происходит.

vk-app-login-success

Загрузка фото

Нам нужно практически повторить, все что написано выше, только для блока Page.

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

Задача: используя метод photos.getAll вытащите свои фотографии из VK за год, выбранный кнопкой. Отсортируйте их в обратном порядке по лайкам, чтобы самая популярная фото оказалась первой.

После скриншотов есть подсказка: функция, которая делает запрос за фото.

Должно выглядеть следующим образом:

vk-app-photo-by-likes

Подсказка: функция для загрузки фото

Так как я не нашел опцию передачи года, то просто выгрузил все фото, по 200 штук за один запрос. Это несколько избыточно, как и тот факт, что мы вызываем функцию makeYearPhotos, вместо того чтобы один раз загрузить все фото и "разместить" их по годам. Я оставил код из первого издания учебника, чтобы не усложнять пример.

Решение ниже:

.

.

.

.

Решение:

src/actions/PageActions.js

makeYearPhotos и getMorePhotos можно вынести в папку utils, как вспомогательные функции.

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

Исправив редьюсер и отрисовку в компоненте, мы закончим начатое.

src/reducers/page.js

src/components/Page.js

[1] - как вы заметили, мы использовали index в качестве ключа для наших div'ов. Запустите пример, попробуйте поменять года. Возможно, вы словите баг, когда у элементов с одинаковым индексом изображение меняется с задержкой. Проблема в том, что мы использовали индекс для элементов, которые изменяются (а индекс-то остается прежним! Ключ в итоге не изменяется, итого реакт "путается").

Чтобы этого избежать, сделайте ключ уникальным (например, для этого у нас есть id в ответе от VK API):

Теперь наш ключ (key = {entry.id}) уникальный и бага нет.

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

Чтобы проверить ошибку, сделайте в функции запроса фото, поставьте count: -1:

src/actions/PageActions.js

Проблема:

vk-app-error-not-displayed

Решение:

vk-app-error-displayed

Итого: закрепили работу с асинхронными запросами.

Исходный код на текущий момент.

P.S. css тоже был слегка подправлен.

Last updated

Was this helpful?