08Nov

react_13_1

Сегодня мы с Вами поговорим об асинхронных actions. Мы начнем доставать наши статьи из API. Как вы могли  заметить у нас уже работает простенький API для запуска которого нужно зайти в папку simple_api, выполнить в ней команду:

npm install

для того, чтобы там появились свои node models . После этого  у Вас cработает скрипт который запускает несколько процессов одновременно, это видно в package.json в корневой директории:

"scripts": {
    "start": "concurrently \"npm run dev\" \"npm run api\"",
    "api": "node simple_api/server.js",
    "dev": "webpack-dev-server --hot --inline",
    "build": "webpack"
  },

В нашем случае он запускает одновременно npm run dev и npm run api. Один поднимает API а другой запускает webpack dev server. С этих пор у нас на порту 3001 работает простая API:

http://localhost:3001/api/article

а на порту:

http://localhost:8080 – developer’s server.

В реальной жизни часто так и происходит, когда разработкой API занята другая команда, с которой вы можете встречаться достаточно редко. API может находиться у Вас где угодно: локально, удаленно, это не важно. Где-то работает Ваше API, а где-то локально работает Ваш dev server. Посмотрите на webpack.config.js:

devServer: {
        proxy: [{
            path: '/api/*',
            target: 'http://localhost:3001'
        }]

В webpack devServer . Вам нужно будет настроить переадресацию, чтобы не было никаких сrossdomain запросов.  Все что у нас приходит на /api будет проксироваться на вашу API. Сейчас это localhost:3001, а далее это может какой-нибудь удаленный адрес. Вы делаете переадресацию и по обоим адресам у Вас будет доступ до article:

http://localhost:3001/api/article

http://localhost:8080/api/article

Таким образом все то, что будет приходить на localhost:8080 будет попадать на Вашу страницу, а все что приходит на /api будет переадресовываться на Вашу API.

Мы с Вами хотим получать все наши статьи не из fixtures.js, а из API, как в реальной жизни. давайте это реализуем. Сейчас по api\article\у нас отдаются все статьи без текстов, и комментариев. Т.к. получать все данные сразу не имеет никакого смысла, потому что они могут быть достаточно большими. Также комментарии нам придется получать с помощью дополнительного запроса, тогда, когда они нам понадобятся.

Для начала получим список статей из API и отобразим их по привычному адресу:

http://localhost:8080

Для этого сначала установим JQuery.  Установим мы его исключительно для того, чтобы делать AJAX запросы, наберите в console:

npm i jquery --s

Нам нужно сделать запрос на api\article\. Запросы мы будем делать в middlewareт.к. запросы это Side Effect.

Создадим файл /middlewares/api.js.

Сразу же нужно сказать о том, что мы будем разбивать наши actions на START, SUCCESS, FAIL. Зайдем в constants.js и добавим следующую запись:

export const LOAD_ALL_ARTICLES = 'LOAD_ALL_ARTICLES'

export const START = '_START'
export const SUCCESS = '_SUCCESS'
export const FAIL = '_FAIL'

Мы берем action LOAD_ALL_ARTICLESи далее добавляем к нему наши константы в зависимости от того, приходит к нам запрос или нет. Вернемся к /middlewares/api.js и сделаем import JQuery библиотеки и наших констант:

import $ from 'jquery'
import { START, SUCCESS, FAIL } from '../constants'

По аналогии с randomID.js где мы проверяли наличие флажка withRandomIdмы сделаем с API. Мы создадим  action creator , который будет называться LOAD_ALL_ARTICLESв AC/articles.js:

import { DELETE_ARTICLE, LOAD_ALL_ARTICLES } from '../constants'

export function deleteArticle(id) {
    return {
        type: DELETE_ARTICLE,
        payload: { id }
    }
}

export function loadAllArticles() {
    return {
        type: LOAD_ALL_ARTICLES,
        callAPI: '/api/article'
    }
}

Возвращать мы будем такой же плоский объект. И у него будет флажок callAPI (ключ) и значение в виде /api/article. Теперь в middleware мы будем проверять, если у action будет callAPIзначит это тот который нас интересует, если нет то мы будем пропускать его дальше.

Продолжим пиcать логику в /middlewares/api.js:

import $ from 'jquery'
import { START, SUCCESS, FAIL } from '../constants'

export default store => next => action => {
    const { callAPI, type, ...rest } = action
    if (!callAPI) return next(action)

    next({
        type: type + START,
        ...rest
    })

        $.get(callAPI)
            .done(response => next({type: type + SUCCESS, response, ...rest}))
            .fail(error => next({type: type + FAIL, error, ...rest}))
}

Как видно из кода выше, если мы не получаем флажок в виде callAPI мы просто передаем управление дальше. Если же он есть, то мы будем делать JQuery  GET запрос. Прежде чем сделать обращение, мы с Вами передадим управление дальше, сказав, что мы начинаем загрузку. В .done, когда к нам придет ответ, мы возьмем его и передадим управление дальше. Наш type уже будет выглядеть как type + SUCCESSтакже мы с Вами передадим здесь responseи все остальное. Т.к. наш action может пройти через несколько middleware, например через randomID а потом через callAPI. Также поступим и с .fail. В итоге у нас action поделился на два action.

to-be-continued-13

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

15. Уроки Node.js. Асинхронная разработка. Введение.

В реальной жизни очень редко бывает так, что, получив запрос, сервер может тут же на него ответить. Обычно для того, чтобы ответить, серверу нужны какие-то данные. Эти данные он получает либо из базы, либо из какого-то другого источника, например, из файловой системы. В этом примере, используя модуль fs при получении запроса на url ‘/’, считывается файл index.html и выводится посетителю.

Уроки React . Урок 10.

Теперь начнем разбираться в том как, мы работаем с данными. Пока, для отображения статей мы использовали денормализированную структуру. Ее видно в файле fixtures.js. В каждой статье есть вся информация о ней, она напоминает древовидную структуру. Подобная структура удобна для чтения, но она превратит вашу жизнь в ад если вы начнете как-то изменять эти данные. Если у вас будет более или менее сложная структура, где эти зависимости будут пересекаться, например, у статьи есть автор у комментария есть автор, у автора есть своя страница. Если хранить это в том виде как это есть сейчас, то когда вы захотите поменять имя этого автора, вам придется просмотреть все места где даже чисто теоретически он может использоваться и заменить эти данные, и скорее всего Вы что-то пропустите. Поэтому, перед тем как сохранять данные в stores их нормализируют.

Leave a Reply