redux-saga-watch-actions
v0.3.0-0
Published
Easily create watchers to map actions to sagas
Downloads
2,354
Maintainers
Readme
redux-saga-watch-actions
Helper methods for managing sagas that respond to actions. Similar in style to redux-actions
. An alternate take on redux-loop.
Whereas handleActions
maps actions to reducer functions, watchActions
maps actions to sagas.
Installation
yarn add redux-saga redux-saga-watch-actions
NOTE: redux-saga
must be installed as a peer dependency.
Docs
Example
Below is a simple example of using watchActions
. You can see that it is used to create a rootSaga
that uses takeEvery
to call a saga every time a specific action is dispatched.
import { watchActions } from 'redux-saga-watch-actions'
import { INCREMENT, DECREMENT } from './constants'
import { increment, decrement } from './sagas'
const rootSaga = watchActions({
[INCREMENT]: increment,
[DECREMENT]: decrement,
})
export default rootSaga
Comparison to handleActions
Below you can see a reducer being created with handleActions
. Reducers and saga do very different things, however, they are similar in that a reducer function expects to be called whenever a specific action is dispatched.
import { handleActions } from 'redux-actions'
import { INCREMENT, DECREMENT } from './constants'
import { increment, decrement } from './reducers'
const reducer = handleActions({
[INCREMENT]: increment,
[DECREMENT]: decrement,
})
export default reducer
Rewritten example from redux-saga
The example below closely matches the fetchUser
example in the redux-saga readme. We've used watchActions
to create the takeEvery
rootSaga
import { watchActions } from 'redux-saga-watch-actions'
import { call, put } from 'redux-saga/effects'
import Api from '...'
// worker Saga: will be fired on USER_FETCH_REQUESTED actions
const fetchUser = function*(action) {
try {
const user = yield call(Api.fetchUser, action.payload.userId)
yield put({ type: 'USER_FETCH_SUCCEEDED', user: user })
} catch (e) {
yield put({ type: 'USER_FETCH_FAILED', message: e.message })
}
}
const mySaga = watchActions({
['USER_FETCH_REQUESTED']: fetchUser,
})
export default mySaga
What does watchActions
do?
It's a convenience method that removes the boilerplate of having to use takeEvery
to hook your saga up to actions.
Example: without watchActions
It's illuminating to see an example without using watchActions
. Below you can see the basics of what watchActions
does using vanilla redux-saga boilerplate. We are creating a rootSaga
that will capture certain dispatched actions and feed them into a generator function. If you've used redux-saga, you've probably done something similar before.
import { all, takeEvery } from 'redux-saga/effects'
import { runSaga } from './store/sagas'
// grab action constants and sagas from your app
import { INCREMENT, DECREMENT } from './constants'
import { increment, decrement } from './sagas'
// without watch actions
const rootSaga = function*() {
yield all([takeEvery(INCREMENT, increment), takeEvery(DECREMENT, decrement)])
}
runSaga(rootSaga)
Example: with watchActions
How does watchActions
make things easier? It doesn't, really. The watchActions
function is a convenience method. It allows you to quickly create a root saga that marries actions to sagas, similar to how redux marries actions to reducers. The benefit is conceptual parity with handleActions
from redux-actions. Whereas handleActions
maps actions to reducer functions, watchActions
maps actions to sagas.
import { watchActions } from 'redux-saga-watch-actions'
import { runSaga } from './store/sagas'
// grab action constants and sagas from your app
import { INCREMENT, DECREMENT } from './constants'
import { increment, decrement } from './sagas'
// with watch actions
const rootSaga = watchActions({
[INCREMENT]: increment,
[DECREMENT]: decrement,
})
runSaga(rootSaga)
Usage
watchActions(sagaMap)
import { watchActions } from 'redux-saga-watch-actions'
This creates a rootSaga
from the sagaMap
which will use takeEvery
to map actions to sagas. Internally, this calls createWatcher()
to create a saga for each action type.
import { watchActions } from 'redux-saga-watch-actions'
import { INCREMENT, DECREMENT } from './constants'
import { increment, decrement } from './sagas'
const rootSaga = watchActions({
[INCREMENT]: increment,
[DECREMENT]: decrement,
})
export default rootSaga
createWatcher(actionType, saga)
import { createWatcher } from 'redux-saga-watch-actions'
You don't normally need to call createWatcher
yourself. Used internally by watchActions
. Returns a generator function that uses takeEvery(actionType, saga)
to respond to dispatched actions. Compare to mySaga
in the redux-saga usage example.
import { createWatcher } from 'redux-saga-watch-actions'
import { INCREMENT } from './constants'
import { increment } from './sagas'
const mySaga = createWatcher(INCREMENT, increment)
export default mySaga
Middleware
You might want to read about the included middleware.