Our Blog

Let us find tech solutions together

Nov 20

Simplifying the Redux Saga entry file

By Andrew Lombardi | Comments

 


From georigami on flickr

My entry file with Redux Saga generally looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import {all} from "redux-saga/effects";

import {
    watchLoginRequest,
    watchLogoutRequest,
    watchCurrentUserRequest,
    watchUpdateProfileRequest
} from "./authSaga";

import {
    watchGetUserList,
    watchGetUser,
    watchAddUser,
    watchUpdateUser,
    watchDeleteUser
} from "./adminSaga";

export default function* rootSaga() {
    yield all([
        watchLoginRequest(),
        watchLogoutRequest(),
        watchCurrentUserRequest(),
        watchUpdateProfileRequest(),
        watchGetUserList(),
        watchGetUser(),
        watchAddUser(),
        watchUpdateUser(),
        watchDeleteUser(),
    ]);
}

As you can see a set of imports and then an array of functions added to the generator function used in my store module. This works fine, but I often find that swapping between a specific sagas file and the rootSagas file to be an unnecessary step prone to error.

In the individual saga, these list of functions that get called are pointing to non-blocking yields to handle the action types spawned from the action creators that in turn will call a generator function to handle that action type:

1
2
3
export function* watchLoginRequest() {
    yield* takeEvery(types.LOGIN_REQUEST, loginRequest);
}

These work fine, can be organized near the end of your individual sagas files, but the way I had it setup, contained too many places to edit and possibly miss.

I’ve taken the liberty of using some ES7 magic to fix my pain. Here’s the new rootSaga.js:

1
2
3
4
5
6
7
8
9
10
import {all} from "redux-saga/effects";
import { sagas as authSagas } from "./authSaga";
import { sagas as adminSagas } from "./adminSaga";

export default function* rootSaga() {
    yield all({
        ...authSagas,
        ...adminSagas,
    });
}

I like this a lot more, and when you have more than one saga, you can see how we just use the spread operator to combine things nicely. As an example in one of our saga files, here’s how we can handle our watch generator functions:

1
2
3
4
5
6
export const sagas = {
    watchCurrentUserRequest: takeEvery(types.CURRENT_USER_REQUEST, currentUserRequest),
    watchUpdateProfileRequest: takeEvery(types.UPDATE_PROFILE_REQUEST, updateProfileRequest),
    watchLoginRequest: takeEvery(types.LOGIN_REQUEST, loginRequest),
    watchLogoutRequest: takeEvery(types.LOGOUT_REQUEST, logoutRequest),
};

Can you see any way to inject any further brevity into the above? This pattern is common in a lot of our teams redux-saga code, and I like the way this looks for refactoring.