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
}
Concepts
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
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')