Reputation: 2478
Today checking codebase with my team we encounter that we have a mix of dispatch an action with put or call a saga directly with the call method. I always dispatch the action with the put but dunno if call the saga directly is wrong or it's the same.
Any clarification or documentation on this?
function* anotherSaga() {
yield* put(logoutRequest({ tokenExpired: true }));
}
function* anotherSaga() {
yield* call(logoutSaga, {payload: { tokenExpired: true }});
}
export function* watchRemoteConfigSaga() {
yield* takeEvery(logoutRequest, logoutSaga);
yield* takeEvery(anotherSaga, anotherSaga);
}
Upvotes: 1
Views: 972
Reputation: 1
Both are fine, but different.
yield call(logoutSaga)
invokes the logoutSaga function and waits for its completion. It is a synchronous call, like a generic function call, which can also return result if needed, for example boolean indicating logout success.
yield put(logoutRequest())
dispatches the logoutRequest action to the Redux store which is handled asynchronously. It may trigger reducers and other sagas in the process, which subscribed for this action.
Upvotes: 0
Reputation: 4975
Both options are fine.
The way I like to think about it is that redux actions are essentially events. So if I just want to let the rest of the application know that something happened I will dispatch an action and the rest of the app can react to it, but for the original saga it doesn't matter either way. If its something that is part of the expected functionality of the original saga then it shouldn't be an event but a direct call using the call effect.
Example of an action/event:
function* fetchItemsSaga() {
const data = yield fetch('/items')
yield put(saveItems(data))
}
function* itemListenerSaga() {
yield takeEvery(SAVE_ITEMS, function*(){
console.log('New items are stored')
}
}
Example of a direct call:
function* fetchItemsSaga() {
const data = yield fetch('/items')
// in this case, the logic in saveItemsSaga is necessary functionality of fetchItemsSaga
yield call(saveItemsSaga, data)
}
function* saveItemsSaga(data) {
console.log('New items are stored')
yield put(saveItems(data))
}
Notice how the contract changes in the first case the itemListenerSaga
depends on fetchItemsSaga
while in the second case fetchItemsSaga
depends on saveItemsSaga
- this will likely affect how you import stuff in your app and doing this right might be important for correct encapsulation of various layers of your app.
Upvotes: 3