Blog>
Snippets

Structuring Sagas with the Watcher and Worker Pattern

Exemplify structuring sagas using the watcher and worker pattern, where the watcher saga listens for dispatched actions and delegates tasks to worker sagas for handling side effects.
import { takeEvery, call, put } from 'redux-saga/effects';

// Worker saga: will perform the asynchronous task
function* fetchUserData(action) {
    try {
        const userData = yield call(Api.fetchUser, action.payload.userId);
        yield put({type: 'FETCH_USER_SUCCESS', userData});
    } catch (error) {
        yield put({type: 'FETCH_USER_ERROR', message: error.message});
    }
}
This is the worker saga. It performs the actual API call to fetch user data. Upon success or failure, it dispatches corresponding actions.
import { takeEvery } from 'redux-saga/effects';
import { fetchUserData } from './sagas';

// Watcher saga: watches for the 'FETCH_USER_REQUEST' action and starts the worker saga
function* watchFetchUser() {
    yield takeEvery('FETCH_USER_REQUEST', fetchUserData);
}
This is the watcher saga. It listens for 'FETCH_USER_REQUEST' actions and delegates the task of fetching user data to the worker saga.
import { all } from 'redux-saga/effects';
import { watchFetchUser } from './sagas';

// Root saga: single entry point to start all the sagas at once
export default function* rootSaga() {
    yield all([
        watchFetchUser(),
    ]);
}
This is the root saga where all watcher sagas are combined. It serves as the single entry point for running all sagas.