SIGN IN

Уроки React. Урок 14.

react_14

Всем привет! Продолжаем работу над нашим приложением. Мы с Вами уже умеем делать простые обращения к серверу и в 80% случаев этих знаний будет достаточно для выполнения типовых задач. Но конечно же, как работать с более сложными вещами мы тоже разберемся. Но прежде чем начать с этим разбираться спешу Вас предупредить, что middleware  далеко не всегда надо писать самостоятельно.  Т.к. это такие часто используемые  (переиспользуемые) элементы, которые  уже были написаны до Вас. Рекомендуем ознакомиться с данным ресурсом, здесь можно найти огромное количество разнообразных  middlewares и т.д.  К примеру вот готовый logger. Мы писали с Вами logger чтобы попрактиковаться, но вот пример прекрасного готового решения.

Иногда бывает так, что мы хотим выполнить dispatch нескольких actions. Например в AC/articles.js deleteArticle мы делаем dispatch одного action. Но иногда нам нужно проделать это над несколькими actions . Чтобы каждый раз не писать для этого middleware  мы можем просто вернуть массив type:'OTHER_ACTION" 

и чтобы они были  dispatch (‘задиспачились’) один за другим. Для этого существует middleware redux-multi. Как она работает?
Вспомните как мы с вами делали проверку – интересует ли нас какой-то action или нет? Мы делали проверку по какому-либо флажку (как в middlewares/api.js), но можно это сделать и по-другому. Например, мы знаем, что в reducers должны попасть “плоские” объекты. Поэтому мы можем сделать проверку по типу. Если тип не объект, а массив – то разбить их и сделать dispatch одного за другим.  Это и делает redux-multi. Если к нему приходит массив с actionsон делает dispatch одного за другим.  Нужно понимать, что разбивка на action происходит внутри  middleware, но вы пишите их в одном месте для удобства (в action creator). И пожалуй самая популярная middleware в Redux это redux-thunk. По аналогии redux-multi он проверяет по типу что к нему приходит, и если это не объект а функция, то он вызывает ее внутри себя и далее уже происходит dispatch.  С его помощью можно делать асинхронные actions(на самом деле как бы асинхронные). Например загрузку статей мы смогли бы описать несколько по-другому.

Установим redux-thunk:

npm i redux-thunk --S

Зайдем в AC/articles.js и добавим:

Мы возвращаем функцию у которой будет доступ к dispatch, здесь мы скопировали часть логики из middlewares/api.js, чтобы не писать дважды, конечно же предварительно немного её изменив . Мы будем делать тоже самое действие, что и до этого, просто другим способом.

Также изменим import в этом же файле:

Не забудем подключить эту middleware в store, для этого перейдем в store/index.js и добавим:

И поставим ее где-то в самом начале, так как все наши middleware ожидают какого-то объекта, а если они получат не объект а функцию, у нас могут появиться ошибки.

А поставив redux-thunk первым номером он проверит –  приходит функция или нет, если да, то будет работать с ней, если нет, передаст управление в другие middlewares. Теперь убедимся, что у нас все работает, но предварительно  зайдем в containers/Articles.js и изменим один из import таким образом:

И в этом же файле в export defaults изменим функцию которую мы вызываем на loadAllArticlesAlt:

Проверяем, все должно прекрасно работать! Посмотрите, мы пишем асинхронные actions, (к примеру, взгляните на код в AC/articles.js) прямо в action creator, хотя на самом деле, код который мы написали исполняется в middlewares. Здесь можно писать достаточно сложную логику, также у вас есть доступ к состоянию store:

Таким образом вы можете добавить что-то из store для реализации нужной вам логики.

Мы подключили redux-thunk вместе с остальными middleware в store, он проверяет тип action который к нему пришел. Когда вы пишите middleware Вам зачастую нужно проверить , что за action к Вам пришел, интересует ли его эта middleware или вам необходимо передать управление дальше. Мы делали проверки по флажку, к  примеру как в middlewares/randomId.js , а redux-thunkделает проверку по типу. Если к нему пришла функция, то он ее вызывает, примерно вот таким образом:action(next, store.getState()). (action это наша функция). А уже этот этот action (эту функцию) мы описали самостоятельно в Action Creator, в  AC/articles.js, а конкретно в loadAllArticlesAlt(), а redux-thunk ее вызывает, передав как аргумент состояние store и возможность dispatch  ваш action дальше. И мы этим пользуемся, мы берем и делаем dispatch над LOAD_ALL_ARTICLES + START в AC/articles.js:

Далее делаем асинхронные обращения к API, ждем чего-то, далее делаем еще один dispatch уже LOAD_ALL_ARTICLES + SUCCESS или FAIL . Пишем мы эту логику прямо в Action creator. Поскольку мы здесь имеем доступ к состоянию store , а также  возможность сделать dispatch нескольких actions, возможно они будут асинхронные и.т.п. – это то, что чаще всего нам нужно в middlewares .

Таким образом redux-thunk позволяет нам не писать лишние middlewares. Если нам нужно реализовать какую-то сложную логику, которую вы  не будете переиспользовать (т.е. она будет использоваться в одном месте), вы можете просто обернуть это в функцию  добавив ее в Action Creator и далее использоватьredux-thunk

Если нужно выполнить отложенный вызов, то вы тоже делаете это в middleware. В Action creator такой опции нет, это просто чистая функция, которая возвращает объект. Также мы не можем сделать return через setTimeout. Поэтому Вам придется сделать что-то наподобие такого в вашем Action Creator AC/articles.js :

Почему redux-thunk все же не так хорош? Очень многие разработчики забывают о middlewares совсем. Наш совет состоит в том, чтобы помнить, что обращения к серверу делается в middlewares. Не стоит писать всю логику в action creators с использованием redux-thunk. Ну или нужно отдавать себе отчет, зачем вы это делаете. Нужно помнить, что actions должны всегда быть чистыми функциями, поэтому не стоит писать в них например генерацию случайного id.  Подобные решения ставят крест на дальнейшем переводе приложения в разряд тех где присутствует серверный рендеринг. В чем вся прелесть middlewares – в том что это централизованное место для всех Side Effects. Т.е. когда вы захотите перенести эту бизнес-логику на сервер или React-native, вы теоретически сможете использовать многое из уже существующей логики, тогда как изменениям может подвергнуться только сама middleware.

Домашнее задание – сделать загрузку комментариев, чтобы по клику на show comments комментарии у Вас загружались с сервера. Таким образом, загрузка комментариев будет выполняться с такого  адресу (к примеру) , где в конце находится id статьи:

http://localhost:8080/api/comment?article=56c782f18990ecf954f6e027

Код урока вы можете скачать здесь.

keep-calm14

 

We are looking forward to meeting you on our website soshace.com

About the author

Stay Informed

It's important to keep up
with industry - subscribe!

Stay Informed

Looks good!
Please enter correct name
Please enter correct email
Looks good!

Related articles

Уроки Express.js . Логгер, Конфигурация, Шаблонизация с EJS. Часть 2.

Favicon – это все connect Middleware, он смотрит, если url имеет вид favicon.ico, то он читает favicon и>>>

Programming

3. Уроки Express.js. Шаблонизация с EJS: Layout, Block, Partials

В реальной жизни у нас обычно больше, чем один шаблон. Более того, если уж так>>>

Programming
24.11.2016

Уроки Express.js. Основы и Middleware. Часть 2.

Всем привет! Давайте продолжим наш урок об основах Express и Middleware. Итог (добавим в>>>

Programming

No comments yet

Sign in

Forgot password?

Or use a social network account

 

By Signing In \ Signing Up, you agree to our privacy policy

Password recovery

You can also try to

Or use a social network account

 

By Signing In \ Signing Up, you agree to our privacy policy