Giter VIP home page Giter VIP logo

redux-saga-watch-actions's Introduction

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.

redux-saga-watch-actions's People

Contributors

heygrady avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

redux-saga-watch-actions's Issues

Uncaught Error: createSagaMiddlewareHelpers expects a sagaMiddleware to include a run method

I tried to use the redux-saga-watch-actions library, but for now I stuck on some unresercheble error on the whole internet. The reason of it I cannot imagine, because I do all as said in the original manual of this useful package.

My sagaHelper file

import createSagaMiddleware from 'redux-saga'
import createSagaMiddlewareHelpers from 'redux-saga-watch-actions/lib/middleware'
import watchSearch from '../routes/watchSearch/modules/saga'
import watchHub from '../modules/saga'

const sagaMiddleware = createSagaMiddleware()
const runSaga = saga => sagaMiddleware.run(saga)

const { injectSaga, cancelTask } = createSagaMiddlewareHelpers(runSaga) // 

export const rootSaga = function * () {
  yield all([
    watchHub(),
    watchSearch()
  ])
}

export { cancelTask, injectSaga, runSaga }
export default sagaMiddleware

My createStore file:

import saga, { rootSaga, runSaga } from '../saga/sagaHelper'

export default (initialState = {}) => {

  const store = createStore(
    makeRootReducer(),
    initialState,
    compose(responsiveStoreEnhancer, applyMiddleware(saga))
  )

  store.runSaga = runSaga
  runSaga(rootSaga)

  return store
}

Used Webpack 3.8.1, React 16. Redux - latest

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.