I use Redux-Saga in situations where there is complex business logic that is best separated from the component. We are adopting RTK Query and aren't able to use the endpoints manually. Yes, I am aware that Redux best practices docs suggest using Thunk when at all possible.
This particular saga task example doesn't make a great case for using Redux-Saga but there are definitely situations where the business logic is so involved/long/complex that it doesn't belong in a component and where we use saga functionality that can't be (elegantly) emulated with a simple Thunk. In this example I want to make a simple mutation (post request) on the backend:
export function* addNewCustomerTask(action: ReturnType<typeof addNewCustomer>) {
const { name, industry, defaultIdentifierObfuscationLevel } = action.payload
if (!name) {
yield put(setToast({ text: 'Name can not be empty', style: ToastStyle.Error }))
}
else if (!industry) {
yield put(setToast({ text: 'Industry can not be empty', style: ToastStyle.Error }))
}
else if (!defaultIdentifierObfuscationLevel) {
yield put(setToast({ text: 'Default identifier obfuscation level can not be empty', style: ToastStyle.Error }))
}
else {
try {
yield call(authApiEndpoints.addCustomer.initiate, action.payload)
}
catch {
console.error('Error')
}
}
}
The yield call(authApiEndpoints.addCustomer.initiate, action.payload)
statement doesn't do anything.
How do you perform a mutation inside of a Saga?
It's an action creator, you need to put
it's execution result.
// start it
const promise = yield put(authApiEndpoints.addCustomer.initiate(action.payload))
// wait until finished
yield promise;
// do something with it
// unsubscribe data - will be removed from store.
promise.unsubscribe()
As for the typings:You might need to extend the types of put
for typed-redux-saga
something like that:
(I couldn't test it, so if you have to fix something up please submit an edit to this answer)
Based on https://github.com/agiledigital/typed-redux-saga/blob/591955fa5bdd73ae6f668f27a049fde21a7ffb6f/types/index.d.ts#L175-L177
and https://github.com/reduxjs/redux-thunk/blob/290acf90fa5afac5b49f286bb3d8fc51aa864ed3/src/index.d.ts#L25-L27
declare module 'typed-redux-saga' {
export function put<TReturnType>(
thunkAction: ThunkAction<TReturnType, TState, TExtraThunkArg, TBasicAction>,
): SagaGenerator<TReturnType, PutEffect<TReturnType>>;
}