# Using Sagas * Sagas connect as middleware to a redux store. * Sagas run like cuncurrent worker tasks and have to be started for that. ```jsx // main.js import { createStore, applyMiddleware } from 'redux' import createSagaMiddleware from 'redux-saga' import { rootSaga } from './sagas' const sagaMiddleware = createSagaMiddleware() const store = createStore( reducer, applyMiddleware(sagaMiddleware) ) sagaMiddleware.run(helloSaga) ``` * Asynchronous actions need to be split into more tasks to the dispatcher, so reducers can always return immediately: ```jsx // actions.js function increment(payload) { return { type: 'INCREMENT_REQUEST', payload } } // reducers.js export default function counter(state = 0, action) { switch (action.type) { case 'INCREMENT_REQUEST': // disable button // print message /* YOU DON'T NEED TO CALL THE FUNCTION HERE. IT'S INTERCEPTED BY THE MIDDLEWARE. */ return state case 'INCREMENT_SUCCESS': return state + 1 case 'INCREMENT_FAIL': // print error message default: return state } } // sagas.js import { call, put, takeEvery } from 'redux-saga/effects' // Worker export function * incrementAsync () { try { const data = yield call(Api.isIncrementOk) yield put({ type: 'INCREMENT_SUCCESS', data }) } catch (error) { yield put({ type: 'INCREMENT_FAIL', error}) } } // Watcher (intercepts INCREMENT_REQUEST, dispatches INCREMENT_SUCCESS or INCREMENT_FAIL in return.) export function * watchIncrementAsync() { yield takeEvery('INCREMENT_REQUEST', incrementAsync) } // export all sagas in parallel export default function * rootSaga() { yield takeEvery('INCREMENT_REQUEST') yield takeEvery('DECREMENT_REQUEST') } ``` ## Saga helpers * Yield 'effects', in 'redux-saga/effects' * `takeEvery` handles every action of a type that is dispatched. * Allows multiple `incrementAsync` instances to be started concurrently. * `takeLatest` in contrast only takes the response of the latest requested action. * Allows only one `incrementAsync` to run at a time * If another task is requested, the previous is automatically cancelled. * You can start multiple sagas which behave like they were forked. ## Declarative effects * Effects are plain JavaScript objects expressing Saga logic. * they contain information to be interpreted by the middleware. * Sagas can yield effects in multiple forms, the easiest are promises * Use `call` to call functions. Call returns on object describing to the middleware what to do. This is similar to action creators, which describe actions for the reducer. * For testing, you can just check whether the effect object ist correct, you don't need to actually call the async function. - ## Dispathing actions to the store