Getting started with Redux Saga

You can not make API calls (or any other side effects) inside the reducers. For that you must use middleware. Redux Saga is one such middleware, which is good for

  • async things like data fetching
  • impure things like accessing browser cache

Generator functions

Redux Saga uses Generator functions, an ES6 feature.

With ES6 generators, we have a different kind of function, which may be paused in the middle, one or many times, and resumed later, allowing other code to run during these paused periods.

  • They are denoted with a *, e.g. function* foo() {}
  • We pause function with the yield keyword, from inside the function
  • We restart the function from the outside, can not be restarted from within the function once it’s paused
function* foo () {
  // code goes here


Watcher and worker sagas

// Worker
function* getUsers() {
  try {

  } catch(e) {


// Watcher
function* watchGetUsers() {
  yield takeEvery(users.actions.getUsers, getUsers) // when this action is dispatched, run this function

Blocking and non-blocking sagas

| Blocking | Non-blocking | |-|-| | takeEvery | |

Common effects

  1. call() makes a function call. Could be another generator, or an API call, or a helper function imported from another file. We can yield a Promise directly,
const products = yield Api.fetch('/products')

but that makes unit testing difficult. So we use call() instead

// call(fn, ...args)
const products = yield call(Api.fetch, '/products')