Диспатчим action в Store

Следуя предыдущему примеру, предположим, что после каждого сохранения мы хотим отправить какое-либо действие, чтобы уведомить Store о том, что получение данных прошло успешно (в данный момент мы не будем думать о возможных ошибках при получении данных).

Мы могли бы поместить функцию dispatch в генератор и затем генератор может вызвать его (dispatch) после получения ответа:

// ...

function* fetchProducts(dispatch) {
  const products = yield call(Api.fetch, '/products')
  dispatch({ type: 'PRODUCTS_RECEIVED', products })
}

Однако это решение имеет те же недостатки, что и функции вызываемые непосредственно изнутри генератора (как было сказано в предыдущем разделе). Если мы хотим проверить, что fetchProducts выполняет отправку после получения ответа от AJAX, то нам придется опять создавать mock-функцию dispatch.

Вместо этого нам нужно декларативное решение. Просто создайте объект что бы указать middleware что нам нужно диспачить action и позвольте middleware выполнить настояющию отправку1. Таким образом, мы можем проверить отправку генератора таким же образом: просто проверив полученный эффект через полученый от генератора и убедится, что он содержит правильные инструкции.

Для этой цели библиотека предоставляет функцию put который диспатчит Effect.

import { call, put } from 'redux-saga/effects'
// ...

function* fetchProducts() {
  const products = yield call(Api.fetch, '/products')
  // создаем и диспатчим Effect
  yield put({ type: 'PRODUCTS_RECEIVED', products })
}

Теперь мы можем легко написать тест для генератора, как в предыдущем разделе

import { call, put } from 'redux-saga/effects'
import Api from '...'

const iterator = fetchProducts()

// expects a call instruction
assert.deepEqual(
  iterator.next().value,
  call(Api.fetch, '/products'),
  "fetchProducts should yield an Effect call(Api.fetch, './products')"
)

// создаем фейковый ответ с сервера
const products = {}

// ожидает диспатча
assert.deepEqual(
  iterator.next(products).value,
  put({ type: 'PRODUCTS_RECEIVED', products }),
  "fetchProducts should yield an Effect put({ type: 'PRODUCTS_RECEIVED', products })"
)

Обратите внимание, как мы передаем фейковый ответ генератору с помощью метода next. Во вне middleware мы имеем полный контроль над генератором, мы можем имитировать реальную среду с простым фейковым результатом и и возабновить генератор с ними. Mocking данные намного проще, чем mock-функции и [spying calls].

1. Just create an Object to instruct the middleware that we need to dispatch some action, and let the middleware perform the real dispatch.

results matching ""

    No results matching ""